区间最大值 II
Time Limit: 1000 MS Memory Limit: 65535 K
Total Submit: 485(160 users) Total Accepted: 175(115 users) Rating: Special Judge: No
Description
给一个有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
题目数据已更新。
本题就是一道简单的线段树题目,个人是在线段树建树的时候就对每个区间的最大值找出来,然后把其输出就OK了。
下面是AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
int left,right,val;
} c[300005];
void build_tree(int root,int l,int r)
{
c[root].left=l;
c[root].right=r;
if(c[root].left==c[root].right)
{
scanf("%d",&c[root].val);
return ;
}
int mid=(c[root].left+c[root].right)/2;
build_tree(root*2,l,mid);
build_tree(root*2+1,mid+1,r);
c[root].val=max(c[root].val,max(c[root*2].val,c[root*2+1].val));
}
int search_tree(int root,int l,int r)
{
if(c[root].left==l&&c[root].right==r)
{
return c[root].val;
}
int mid=(c[root].left+c[root].right)/2;
int x;
if(mid<l)
{
return x=search_tree(root*2+1,l,r);
}
else if(mid>=r)
{
return x=search_tree(root*2,l,r);
}
else
{
int x1=search_tree(root*2,l,mid);
int x2=search_tree(root*2+1,mid+1,r);
x=max(x1,x2);
return x;
}
}
int main()
{
int t=0,n,q;
while(~scanf("%d",&n))
{
t++;
for(int i=0; i<=n; i++)
{
c[i].val=0;
}
build_tree(1,1,n);
scanf("%d",&q);
printf("Case %d:\n",t);
while(q--)
{
int a,b;
scanf("%d%d",&a,&b);
int re=search_tree(1,a,b);
printf("%d\n",re);
}
}
return 0;
}