线段树求解区间最大最小值(模板)

题目描述

第一行:输入两个正整数;

第二行:输入n个整数 大小范围为[1,100000];

接下来的m行,每次两个正整数l,r (1<=l<=r<=n);

输出

[l,r].

示例输入

6 3
1
7
3
4
2
5
1 5
4 6
2 2

示例输出

6
3
0

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define LL long long
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
int ma[1000000];
int mi[1000000];
void Up(int rt)
{
    ma[rt]=max(ma[rt<<1],ma[rt<<1|1]);
    mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);
}
void built(int l,int r,int rt)
{
    if(l==r)
    {
        scanf("%d",&mi[rt]);
        ma[rt]=mi[rt];
        return ;
    }
    int mid=(l+r)>>1;
    built(lson);
    built(rson);
    Up(rt);
}
int Q1(int x,int y,int l,int r,int rt)
{
    if(x<=l&&y>=r)
    {
        return ma[rt];
    }
    int mid=(l+r)>>1;
    if(y<=mid)
    {
        return Q1(x,y,lson);
    }
    else if(x>mid)
    {
        return Q1(x,y,rson);
    }
    else
        return max(Q1(x,y,lson),Q1(x,y,rson));
}
int Q2(int x,int y,int l,int r,int rt)
{
    if(x<=l&&y>=r)
    {
        return mi[rt];
    }
    int mid=(l+r)>>1;
    if(y<=mid)
    {
        return Q2(x,y,lson);
    }
    else if(x>mid)
    {
        return Q2(x,y,rson);
    }
    else
        return min(Q2(x,y,lson),Q2(x,y,rson));
}
int main()
{
    int n,m,i,j,k;
    while(~scanf("%d%d",&n,&m))
    {
        built(1,n,1);
        while(m--)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d\n",Q1(x,y,1,n,1)-Q2(x,y,1,n,1));
        }

    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 10:09:11

线段树求解区间最大最小值(模板)的相关文章

poj 3264 线段树 求区间最大最小值

Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous rang

POJ--3468(线段树,区间修改,模板)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072KB   64bit IO Format: %I64d & %I64u Submit Status Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to ad

Balanced Lineup(线段树之区间查找最大最小值)

传送门 线段树的区间查找最大最小值模板. 裸的线段树 #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <queue> #include <vector> #include <cstdlib> #include <algorithm> #define ls

模板 线段树的区间修改

线段树的区间修改 区间绝对标记 改成同一个数 注意打标记前 要先判断 是否有标记 这道题不能像加法标记一样 标记初始化为 0 如果这道题 可以将数变成 0 那么0 就不能为初始值了 然后我们初始值要选择一个不会被干扰到的数字 比如 -1 就不会变成 -1 另外还要注意在标记清空时 要将标记 变成 -1 而不是 0 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstr

线段树_区间加乘(洛谷P3373模板)

题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字的个数.操作的总个数和模数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k 操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k

(转)线段树的区间更新

原文地址:http://blog.csdn.net/zip_fan/article/details/46775633 写的很好,昨天刚刚开始写线段树,有些地方还不是很明白,看了这篇博文,学会了数组形式保存线段树,还学会了区间更新 以下为转载的博文内容 距离第一次接触线段树已经一年多了,再次参加ACM暑假集训,这一次轮到我们这些老家伙们给学弟学妹们讲解线段树了,所以就自己重新把自己做过的题目看了一遍,然后写篇博客纪念一下.作为一个菜鸟,文中肯定有很多表达不是很准确甚至错误的地方,欢迎各位大牛指正.

线段树(大三的模板)

Up函数 用来更新父亲节点的值 void push(int w) { sum[w] = sum[2*w]+sum[2*w+1];//更新节点值 } 单点更新 先找出第p个数 然后更新他的值 void add(int p,int d,int l,int r,int w) { if(l==r) { sum[w]+=d; return ; } int m = (l+r)/2; if(p<=m) add(p,d,l,m,2*w); else add(p,d,m+1,r,2*w+1); push(w);

CodeForces 52C Circular RMQ(区间循环线段树,区间更新,区间求和)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://codeforces.com/problemset/problem/52/C You are given circular array a0,?a1,?...,?an?-?1. There are two types of operations with it: inc(lf,?rg,?v) - this operation increases each element on the segm

hiho一下20周 线段树的区间修改

线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了小Ho: 假设货架上从左到右摆放了N种商品,并且依次标号为1到N,其中标号为i的商品的价格为Pi.小Hi的每次操作分为两种可能,第一种是修改价格--小Hi给出一段区间[L, R]和一个新的价格NewP,所有标号在这段区间中的商品的价格都变成NewP.第二种操作是询问--小Hi给出一段区间[L, R]