区间最大值 II | |||||
| |||||
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 |
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#define max(a,b) ((a) > (b) ? (a) : (b))
struct node {
int lvalue, rvalue; //左右边界的值。
int v; //这个节点中的最大值。
struct node *pl, *pr; //左右孩子的指针。
};
//构建一个左右边界从a到b的线段树,返回指向跟节点的指针。
struct node *buildtree(int a, int b)
{
struct node *p = (struct node*)malloc(sizeof(struct node));
p->lvalue = a;
p->rvalue = b;
p->v = INT_MIN; //节点中最大值初始化为最小的整数。
if(a == b) return p;
p->pl = buildtree(a, (a+b)/2);
p->pr = buildtree((a+b)/2 + 1, b);
return p;
}
//插入函数。参数:指向节点的指针p,要插入的位置pos,要插入的值val。
void insert(struct node *p, int pos, int val)
{
//找到了位置,插入val.
if(p->lvalue == p->rvalue) {
p->v = val;
return ;
}
//如果要插入值的位置pos在该节点的左子树上,则插入左子树上。
//否则插入到右子树上。
if(pos <= (p->lvalue + p->rvalue)/2) {
insert(p->pl, pos, val);
} else {
insert(p->pr, pos, val);
}
//该节点的最大值为该节点左子树和右子树的最大值。
p->v = max(p->pl->v, p->pr->v);
}
//查找函数,在区间a和b中查找最大的值。
int search(struct node *p, int a, int b)
{
int ans = INT_MIN;
//不太好理解啊,画画图吧,可以帮助理解。
if(a <= p->lvalue && b >= p->rvalue) {
return p->v;
}
if(a <= (p->lvalue + p->rvalue)/2) {
int tmp = search(p->pl, a, b);
if( tmp > ans ) ans = tmp;
}
if(b > (p->lvalue + p->rvalue)/2) {
int tmp = search(p->pr, a, b);
if( tmp > ans ) ans = tmp;
}
return ans;
}
//释放内存。
void free_memory(struct node *p)
{
if(p->lvalue == p->rvalue) return;
free_memory(p->pl);
free_memory(p->pr);
free( p );
}
int main()
{
int n, t = 0;
while(scanf("%d", &n) != EOF) {
int i, q;
printf("Case %d:\n", ++t);
struct node *root = buildtree(1, n);
for(i = 1; i <= n; i++) {
int v;
scanf("%d", &v);
insert(root, i, v);
}
scanf("%d", &q);
for(i = 0; i < q; i++) {
int a, b;
scanf("%d %d", &a, &b);
printf("%d\n", search(root, a, b));
}
free_memory( root );
}
return 0;
}