I Hate It
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 33469 Accepted Submission(s): 13168
Problem 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。
在每个测试的第一行,有两个正整数 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代码: 线段树之单点更新
代码:
1 #include<stdio.h> 2 #define maxn 200001 3 int aa[maxn<<2]; 4 struct node 5 { 6 int lef,rig,maxc; 7 int mid(){ return lef+((rig-lef)>>1); } 8 }; 9 node seg[maxn<<2]; 10 void build(int left ,int right ,int p) 11 { 12 seg[p].lef=left; 13 seg[p].rig=right; 14 seg[p].maxc=0; 15 while(left==right) 16 { 17 seg[p].maxc=aa[left]; 18 return ; 19 } 20 int mid=seg[p].mid(); 21 build(left,mid,p<<1); 22 build(mid+1 ,right,p<<1|1); 23 if(seg[p<<1].maxc<seg[p<<1|1].maxc) 24 seg[p].maxc=seg[p<<1|1].maxc; 25 else 26 seg[p].maxc=seg[p<<1].maxc; 27 } 28 void updata(int pos ,int p,int val) 29 { 30 if(seg[p].lef==seg[p].rig) 31 { 32 seg[p].maxc=val ; 33 return ; 34 } 35 int mid=seg[p].mid(); 36 if(pos<=mid) updata(pos,p<<1,val); 37 else if(pos>mid) updata(pos,p<<1|1,val); 38 if(seg[p<<1].maxc<seg[p<<1|1].maxc) 39 seg[p].maxc=seg[p<<1|1].maxc; 40 else seg[p].maxc=seg[p<<1].maxc; 41 } 42 int query(int be,int en ,int p) 43 { 44 if(be<=seg[p].lef&&seg[p].rig<=en) 45 return seg[p].maxc; 46 int res2=0,res1=0; 47 int mid=seg[p].mid(); 48 if(be<=mid) res1=query(be,en ,p<<1); 49 if(en>mid) res2=query(be,en ,p<<1|1); 50 if(res1<res2) return res2; 51 else return res1; 52 } 53 int main() 54 { 55 int nn,mm,i,j,sa,sb; 56 char str[3]; 57 while(scanf("%d%d",&nn,&mm)!=EOF) 58 { 59 for(i=1;i<=nn;i++) 60 scanf("%d",&aa[i]); 61 build(1,nn,1); 62 while(mm--) 63 { 64 scanf("%s%d%d",str,&sa,&sb); 65 if(*str=='Q') 66 printf("%d\n",query(sa,sb,1)); 67 else updata(sa,1,sb); 68 } 69 } 70 return 0; 71 }
代码:
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=200005; 4 int aa[maxn]; 5 struct node 6 { 7 int lef,rig; 8 int max; 9 int mid(){ 10 return lef+((rig-lef)>>1); 11 } 12 }; 13 node str[maxn<<2]; 14 inline int max(int a,int b) 15 { 16 return a>b?a:b; 17 } 18 void Build(int left ,int right,int pos) 19 { 20 str[pos].lef=left; 21 str[pos].rig=right; 22 str[pos].max=0; 23 if(left==right){ 24 str[pos].max=aa[left]; 25 return ; 26 } 27 int mid=str[pos].mid(); 28 Build(left,mid,pos<<1); 29 Build(mid+1,right,pos<<1|1); 30 str[pos].max = max( str[pos<<1].max , str[pos<<1|1].max ); 31 } 32 void Update(int ps,int pos,int val) 33 { 34 if(str[pos].lef==ps&&str[pos].rig==ps){ 35 str[pos].max=val; //将这个数值更新 36 return ; 37 } 38 int mid=str[pos].mid(); 39 if(mid>=ps) Update(ps,pos<<1,val); 40 else if(mid<ps) Update(ps,pos<<1|1,val); 41 str[pos].max=max(str[pos<<1].max,str[pos<<1|1].max); 42 } 43 int Query(int st,int en,int pos) 44 { 45 if(str[pos].lef>=st&&str[pos].rig<=en){ 46 return str[pos].max; 47 } 48 int mid=str[pos].mid(); 49 int p1=0,p2=0; 50 if(mid>=st) p1=Query(st,en,pos<<1); 51 if(mid<en) p2=Query(st,en,pos<<1|1); 52 return max(p1,p2); 53 } 54 55 int main() 56 { 57 int n , m,cc,dd; 58 char ss[2]; 59 while(scanf("%d%d",&n,&m)!=EOF) 60 { 61 for(int i=1;i<=n;i++) 62 scanf("%d",aa+i); 63 Build(1,n,1); 64 while(m--) 65 { 66 scanf("%s %d%d",ss,&cc,&dd); 67 if(*ss=='Q') 68 printf("%d\n",Query(cc,dd,1)); 69 else Update(cc,1,dd); 70 } 71 } 72 return 0; 73 }