ACM: I Hate It 解题报告 - 线段树
I Hate It Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Description 很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。 这让很多学生很反感。 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。 Input 本题目包含多组测试,请处理到文件结束。 在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。 学生ID编号分别从1编到N。 第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。 接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。 当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。 当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。 Output 对于每一次询问操作,在一行里面输出最高成绩。 Sample Input 5 6 1 2 3 4 5 Q 1 5 U 3 6 Q 3 4 Q 4 5 U 2 9 Q 1 5 Sample Output 5 6 5 9 Hint Huge input,the C function scanf() will work better than cin
和前面题“敌兵布阵”一样,只要注意把父节点保存子节点最大值就可以了。
AC代码:
1 #include"iostream" 2 #include"algorithm" 3 #include"cstdio" 4 #include"cstring" 5 #include"cmath" 6 #define max(a,b) a>b?a:b 7 #define min(a,b) a<b?a:b 8 #define lson l,m,rt<<1 9 #define rson m+1,r,rt<<1|1 10 using namespace std; 11 const int MX = 200000+10; 12 int maxx[MX<<2]; 13 void PushUp(int rt) { 14 maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]); //更新节点 父节点为子节点中较大的 15 } 16 17 void Build(int l,int r,int rt) { 18 if(r==l) { 19 scanf("%d",&maxx[rt]); 20 return ; 21 } 22 int m=(r+l)>>1; 23 Build(lson);//建立左节点 24 Build(rson);//建立右节点 25 PushUp(rt); //回朔算出建立的每个点的美观值的和 26 } 27 28 void UpData(int p,int mx,int l,int r,int rt) { 29 if(r==l) { //找到并更新目标点 30 maxx[rt]=mx; 31 return ; 32 } 33 int m=(r+l)>>1; 34 if(p<=m) UpData(p,mx,lson); //如果不是目标点向左右寻找 35 if(p >m) UpData(p,mx,rson); 36 PushUp(rt);//将更新过的每个点的子节点的和更新。 37 } 38 39 int Query(int L,int R,int l,int r,int rt) { 40 if(L<=l&&R>=r) //大小超过整个范围 41 return maxx[rt]; //返回该节点的值 42 int m=(r+l)>>1; 43 int ret=0; 44 if(L<= m) ret =max(ret, Query(L,R,lson)); //左节点的值 45 if(R > m) ret =max(ret, Query(L,R,rson)); //右节点的值 46 return ret; 47 } 48 49 int main() { 50 int T,n; 51 int a,b; 52 char s[2]; 53 while(~scanf("%d%d",&n,&T)) { 54 Build(1,n,1); 55 while(T--) { 56 scanf("%s%d%d",s,&a,&b); 57 if(s[0]=='Q') { 58 printf("%d\n",Query(a,b,1,n,1)); 59 } 60 if(s[0]=='U') { 61 UpData(a,b,1,n,1); 62 } 63 } 64 } 65 return 0; 66 }