线段树———C - 区间最大值 II

给一个有n个整数的序列a1, a2, a3, ..., an,然后有q个提问,每个提问为两个整数i、j,(i<=j),请你回答,在ai到aj中,最大值是多少。

注意:1 <= n,q <= 100000, ai在int整型表示的范围内。

Input

有多组测试数据。
每组测试数据的第一行为一个整数n,表示有n个数;
第二行为n个整数,表示a1,a2,..an;
第三行为q,表示q个提问。
接下来有q行,每行两个数i, j, (i <= j)。

Output

每组测试数据先输出一行"Case n:", n从1开始计数;

接下来有q行,每行对应一个提问,每行只有一个整数,为ai到aj间的最大值。

 

Sample Input

3
1 3 2
2
1 2
2 3
4
1 2 3 4
3
1 2
2 4
1 1

Sample Output

Case 1:
3
3
Case 2:
2
4
1

Hint

题目数据已更新。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 400005
int a[N],sum[N];
void build(int l,int r,int rt){
    if(l==r){
        sum[rt]=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(l,mid,2*rt);
    build(mid+1,r,2*rt+1);
    sum[rt]=max(sum[2*rt],sum[2*rt+1]);
}
int query(int l1,int r1,int l,int r,int rt){
    if(l1<=l&&r1>=r) return sum[rt];//注意这里
    int mid=(l+r)/2;
    int ret=0,ret1=0;
    if(l1<=mid){
        ret=max(ret,query(l1,r1,l,mid,rt*2));
    }
    if(r1>mid){
        ret1=max(ret1,query(l1,r1,mid+1,r,rt*2+1));
    }
    return max(ret1,ret);
}
int main()
{
    int n,cnt=0;
    while(~scanf("%d",&n)){
            memset(a,0,sizeof(a));
            memset(sum,0,sizeof(sum));
            cnt++;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        build(1,n,1);
        int q;
        scanf("%d",&q);
        int p=q;
        while(q--){
                int a,b;
            scanf("%d%d",&a,&b);
            if(q==p-1){
                printf("Case %d:\n",cnt);
            }
            int ans=query(a,b,1,n,1);
            printf("%d\n",ans);
        }
    }
    return 0;
}

ps:可还行

posted on 2019-01-27 10:59  湫叶  阅读(125)  评论(0编辑  收藏  举报

导航