题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1754
http://acm.hdu.edu.cn/showproblem.php?pid=1166
都是最基础的线段树,考的知识点就是点更新,区间求和,区间求最大值。再次学线段树,感觉理解加深了一些。
但是写的时候还是会出现各种奇葩的错误。唉。
hdu1754
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <map> 9 #include <set> 10 #include <vector> 11 #include <cmath> 12 #include <algorithm> 13 #define lson l, m, rt<<1 14 #define rson m+1, r, rt<<1|1 15 using namespace std; 16 typedef long long int LL; 17 const int MAXN = 0x3f3f3f3f; 18 const int MIN = -0x3f3f3f3f; 19 const double eps = 1e-9; 20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 21 {1,1},{1,-1},{-1,-1}}; 22 const int MAX = 200000+10; 23 int gra[MAX<<2], m , n; 24 void pushup(int rt) 25 { 26 gra[rt] = max(gra[rt<<1], gra[rt<<1|1]); 27 } 28 void build(int l, int r, int rt) 29 { 30 if (l == r) { scanf("%d", &gra[rt]); return; } 31 int m = (l + r) >> 1; 32 build(lson); build(rson); pushup(rt); 33 } 34 void update(int p, int k, int l, int r, int rt) 35 { 36 if (l == r) { gra[rt] = k; return; } 37 int m = (l + r) >> 1; 38 if (p <= m) update(p, k, lson); 39 else update(p, k, rson); 40 pushup(rt); 41 } 42 int query(int L, int R, int l, int r, int rt) 43 { 44 if (L <= l && R >= r) { return gra[rt]; } 45 int m = (l + r) >> 1, ret = 0; 46 if (L <= m) ret = max(ret, query(L, R, lson)); 47 if (R > m) ret = max(ret, query(L, R, rson)); 48 return ret; 49 } 50 int main(void){ 51 #ifndef ONLINE_JUDGE 52 freopen("hdu1754.in", "r", stdin); 53 #endif 54 while (~scanf("%d%d", &n,&m)){ 55 char c[2]; int a, b, i; build(1, n, 1); 56 for (i = 0; i < m; ++i){ 57 scanf("%s%d%d", c, &a, &b); 58 if (c[0] == 'U') update(a, b, 1, n, 1); 59 else printf("%d\n", query(a, b, 1, n ,1)); 60 } 61 } 62 63 return 0; 64 }
这道题目,开始写的时候,建树的时候没有 return ,运行都会失败……
然后改了之后,发现数组开小了,把max<<2 写成了 max……
hdu1166
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <map> 9 #include <set> 10 #include <vector> 11 #include <cmath> 12 #include <algorithm> 13 #define lson l, m, rt<<1 14 #define rson m+1, r, rt<<1|1 15 using namespace std; 16 typedef long long int LL; 17 const int MAXN = 0x3f3f3f3f; 18 const int MIN = -0x3f3f3f3f; 19 const double eps = 1e-9; 20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 21 {1,1},{1,-1},{-1,-1}}; 22 const int MAX = 55555; 23 int gra[MAX<<2]; 24 void pushup(int rt) 25 { 26 gra[rt] = gra[rt<<1] + gra[rt<<1|1]; 27 } 28 void build(int l, int r, int rt) 29 { 30 if (l == r) { scanf("%d", &gra[rt]); return; } 31 int m = (l + r) >> 1; 32 build(lson); build(rson); pushup(rt); 33 } 34 void update(int p, int k, int l, int r, int rt) 35 { 36 if (l == r) { gra[rt] += k; return; } 37 int m = (l + r) >> 1; 38 if (p <= m) update(p, k, lson); 39 else update(p, k,rson); 40 pushup(rt); 41 } 42 int query(int L, int R, int l, int r, int rt) 43 { 44 if (L <= l && R >= r) return gra[rt]; 45 int m = (l + r) >> 1, sum = 0; 46 if (L <= m) sum += query(L, R, lson); 47 if (R > m) sum += query(L, R, rson); 48 return sum; 49 } 50 int main(void){ 51 #ifndef ONLINE_JUDGE 52 freopen("hdu1166.in", "r", stdin); 53 #endif 54 int t, i, n, j, k, a, b; scanf("%d", &t); char c[20]; 55 for (i = 1; i <= t; ++i) { 56 printf("Case %d:\n", i); scanf("%d", &n); 57 build(1, n, 1); 58 while (~scanf("%s", c)){ 59 if (c[0] == 'E') break; 60 scanf("%d%d", &a, &b); 61 if (c[0] == 'A') update(a, b, 1, n, 1); 62 else if (c[0] == 'S') update(a, -b, 1, n, 1); 63 else if (c[0] == 'Q') printf("%d\n", query(a, b, 1, n, 1)); 64 } 65 } 66 67 return 0; 68 }
这道题目RE了好多次,原因就是读入的时候,如果遇到END就应该立刻退出,我在最后才判断是不是END,也就是多读了数字,而数据里面又没有,所以RE了……
和上一道题目一样,也是,忘了写max<<2……另外这道题目有加有减,用一个Update就行了,传参的时候传成负的不就行了,别像第一遍似的傻乎乎地写一个add,再写一个几乎一样的add……⊙﹏⊙b汗
两道题目都是写第一遍的时候实在找不出错来了,然后就写第二遍的时候才写对的。。这才发现原来错在哪里了。。唉