i hate it hdu 1754 线段树
I Hate It
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9748 Accepted Submission(s): 3656
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
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
6
5
9
1 //刚开始用 g++ 提交,1087ms, 用c++提交484ms,写戳啦。小白的200多ms.
2 //线段树修该元素值, 求区间最大值
3 #include <stdio.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <algorithm>
7
8 using namespace std;
9
10 struct line {
11 int left,right, c; //c为区间的最大值
12 }L[610000]; //此处数组开小了,第一次提交wa..一般数组要开N*3
13 int maxn = 0;
14
15 int g[400000];//保存成绩
16 //递归创建线段树
17 void creat(int l, int r, int n)
18 {
19 int mid;
20 mid = (l + r)/ 2;
21 L[n].left = l, L[n].right = r;
22 if (l == r) {
23 L[n].c = g[l];
24 return;
25 }
26 creat(l, mid, 2 * n) , creat(mid + 1, r, 2 * n + 1);
27 L[n].c = max( L[n * 2].c , L[n * 2 + 1].c);
28
29 }
30 //递归修改值
31 void change(int num, int val, int n)
32 {
33 int mid = (L[n].left + L[n].right)/2;
34
35 if (num == L[n].left && num == L[n].right ) {
36 L[n].c = val;
37 return ;
38 }
39 if (mid >= num)
40 change(num, val, 2 * n);
41 else
42 change(num ,val, 2 * n + 1);
43 L[n].c = max(L[n * 2].c , L[n * 2 + 1].c);
44 }
45 //递归求区间最大值
46 void sum(int l, int r, int n)
47 {
48 int mid;
49 mid = (L[n].left + L[n].right) / 2;
50 if (l == L[n].left && r == L[n].right)
51 {
52 if (L[n].c > maxn)
53 maxn = L[n].c;
54 return;
55
56 }
57 if (mid >= r)
58 sum(l, r, 2 * n);
59 else if (mid < l)
60 sum(l, r, 2 * n + 1);
61 else
62 sum(l, mid, 2 * n), sum(mid + 1, r, 2 * n + 1);
63
64 }
65
66
67 int main( )
68 {
69 int N, M, a, b, i;
70 char ch[10];
71 while (scanf("%d%d", &N, &M) != EOF) {
72 for(i = 1; i <= N; i++)
73 scanf("%d",&g[i]);
74 creat(1, N, 1);
75 //print( );
76 for(i = 1; i <= M; i++)
77 {
78 scanf("%s%d%d",ch, &a, &b);
79 maxn = 0;
80 if (ch[0] == 'U')
81 change(a,b, 1);
82 else if(ch[0] == 'Q')
83 {
84 sum(a, b, 1);
85 printf("%d\n",maxn);
86 }
87 }
88 }
89 return 0;
90 }
posted on 2011-08-15 18:56 more think, more gains 阅读(139) 评论(0) 编辑 收藏 举报