hdu1754 I Hate It(区间最值 & 单点替换)

I Hate It

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 14377    Accepted Submission(s): 5570


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
 
分析:功能:查找区间最值和单点替换。
心得:以前都用动态实现,现在开始转向静态的了,有点不熟练。。
代码一:模板
View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #define N 200000
 4 using namespace std;
 5 
 6 struct Seg_Tree
 7 {
 8     int max,lift,right;
 9 }tree[4*N];
10 
11 int MAX(int a,int b)
12 {
13     return a>b?a:b;
14 }
15 
16 void buildtree(int r,int a,int b)
17 {
18     tree[r].max=0;
19     tree[r].lift=a;tree[r].right=b;
20     if(a<b)
21     {
22         int m=(a+b)>>1;
23         buildtree(r<<1,a,m);
24         buildtree((r<<1)+1,m+1,b);
25     }
26 }
27 
28 void update(int r,int i,int key)
29 {
30     if(tree[r].lift==i&&i==tree[r].right)
31     {
32         tree[r].max=key;return ;
33     }
34     if(tree[r].lift<=i&&i<=tree[r].right)
35     {
36         if(tree[r].max<key)
37         {
38             tree[r].max=key;
39         }
40         int m=(tree[r].lift+tree[r].right)>>1;
41         if(i<=m)update(r<<1,i,key);
42         else update((r<<1)+1,i,key);
43     }
44 }
45 
46 int find_max(int r,int a,int b)
47 {
48     if(a<=tree[r].lift&&tree[r].right<=b)
49     {
50         return tree[r].max;
51     }
52     else
53     {
54         int m=(tree[r].lift+tree[r].right)>>1;
55         if(b<=m) return find_max(r<<1,a,b);
56         if(a>m) return find_max((r<<1)+1,a,b);
57         if(a<=m&&b>m) 
58         {
59             return MAX(find_max(r<<1,a,m),find_max((r<<1)+1,m+1,b));//居然忘了reuter = =!!
60         }
61     }
62 }
63 
64 int main()
65 {
66     int n,m,i,a,b,key;
67     char ch;
68     while(scanf("%d%d",&n,&m)!=EOF)
69     {
70         buildtree(1,1,n);
71         for(i=1;i<=n;i++)
72         {
73             scanf("%d",&key);
74             update(1,i,key);
75         }
76         for(i=1;i<=m;i++)
77         {
78             scanf("%s",&ch);//如果使用%c就会读入'\n' 切记!!
79             if(ch=='Q')
80             {
81                 scanf("%d%d",&a,&b);
82                 printf("%d\n",find_max(1,a,b));
83             }
84             else if(ch=='U')
85             {
86                 scanf("%d%d",&a,&key);
87                 update(1,a,key);
88             }
89         }
90     }
91     return 0;
92 }

 

代码二:照hh风格写的,蛮好的可以借鉴的,buildtree在这其实没必要
View Code
 1 #include<iostream>
 2 #define N 800000
 3 using namespace std;
 4 
 5 int tree[N];
 6 
 7 inline int MAX(int a,int b)
 8 {
 9     return a>b?a:b;
10 }
11 
12 void buildtree(int rt,int lson,int rson)
13 {
14     tree[rt]=0;
15     int mid=(lson+rson)>>1;
16     buildtree(rt<<1,lson,mid);
17     buildtree(rt<<1|1,mid+1,rson);
18 }
19 
20 void update(int rt,int lson,int rson,int i,int key)
21 {
22     if(i==lson&&i==rson)
23     {
24         tree[rt]=key;return ;
25     }
26     int mid;
27     if(lson<=i&&i<=rson)
28     {
29         if(tree[rt]<key) tree[rt]=key;
30         mid=(lson+rson)>>1;
31         if(i<=mid) update(rt<<1,lson,mid,i,key);
32         else update(rt<<1|1,mid+1,rson,i,key);
33     }
34 }
35 
36 int find_max(int rt,int lson,int rson,int a,int b)
37 {
38     if(a==lson&&b==rson) return tree[rt];
39     int mid=(lson+rson)>>1;
40     if(b<=mid) 
41         return find_max(rt<<1,lson,mid,a,b);//总喜欢写成 >>
42     if(a>mid) 
43         return find_max(rt<<1|1,mid+1,rson,a,b);
44     if(a<=mid&&b>mid) 
45         return MAX(find_max(rt<<1,lson,mid,a,mid),find_max(rt<<1|1,mid+1,rson,mid+1,b));
46 }
47 
48 int main()
49 {
50     int n,m,a,b,i,key;
51     char ch;
52     while(scanf("%d%d",&n,&m)!=EOF)
53     {
54     //    buildtree(1,1,n);
55         memset(tree,0,sizeof(tree));
56         for(i=1;i<=n;i++)
57         {
58             scanf("%d",&key);
59             update(1,1,n,i,key);
60         }
61         for(i=1;i<=m;i++)
62         {
63             scanf("%s",&ch);
64             if(ch=='Q')
65             {
66                 scanf("%d%d",&a,&b);
67                 printf("%d\n",find_max(1,1,n,a,b));
68             }
69             else 
70             {
71                 scanf("%d%d",&a,&key);
72                 update(1,1,n,a,key);
73             }
74         }
75     }
76     return 0;
77 }

 

posted @ 2012-05-14 18:45  mtry  阅读(251)  评论(0编辑  收藏  举报