哈理工oj(acm.hrbust.edu.cn) 1189【线段树】
区间最大值 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; }