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。
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 }
View Code
代码:
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 }
View Code
编程是一种快乐,享受代码带给我的乐趣!!!