线段数例题2

区间极大值1.0

有一个长度为n的非负整数数列a.
现在有m个询问,每个询问的格式为两个整数x和y表示询问a中,第x个数到第y个数间,最大的一个数是多少。(1<=n,m<=100000)

输入格式:

第一行,两个整数n和m
第二行,n个空格间隔的整数,表示数列a
接下来m行,每行两个整数x和y,表示一个询问

输出格式:

m行,每行对应一个询问的结果

样例输入:
7 3
1 6 5 3 4 9 7
2 6
1 4
3 5
样例输出:
9
6
5

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;

struct node
{
    int a,b,l,r,Max;
};
node tree[200001];
int m,n;
int a[100010],tot=0;
void build(int x,int y)
{
    int now=++tot;
    tree[now].a=x;
    tree[now].b=y;
    tree[now].Max=0;
    if(x<y)
    {
        tree[now].l=tot+1;
        build(x,(x+y)/2);
        tree[now].r=tot+1;
        build((x+y)/2+1,y);
        tree[now].Max=max(tree[tree[now].l].Max,tree[tree[now].r].Max);
    }
    else tree[now].Max=a[x];
}
int getmax(int p,int x,int y)
{
    if(x<=tree[p].a&&tree[p].b<=y) return tree[p].Max;
    int lmax=0,rmax=0,mid=(tree[p].a+tree[p].b)/2;
    if(x<=mid) lmax=getmax(tree[p].l,x,y);
    if(y>mid) rmax=getmax(tree[p].r,x,y);
    return max(lmax,rmax);
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,n);
    for(int i=1;i<=m;i++)
    {
        int q,w;
        cin>>q>>w;
        cout<<getmax(1,q,w)<<endl;
    }
    return 0;
}

 

posted @ 2018-03-03 16:45  DeSpeRadOoo  阅读(97)  评论(0编辑  收藏  举报