hdu1166(线段树单点更新&区间求和模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
题意:中文题诶~
思路:线段树单点更新,区间求和模板
代码:
1 #include <iostream> 2 #include <stdio.h> 3 #define lson l, mid, rt << 1 4 #define rson mid + 1, r, rt << 1 | 1 5 using namespace std; 6 7 const int MAXN = 5e4 + 10; 8 int sum[MAXN << 2]; 9 10 void push_up(int rt){//向上求和 11 sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; 12 } 13 14 //建树 15 void build(int l, int r, int rt){//sum[rt] 对应区间 [l, r] 的和 16 if(l == r){ 17 scanf("%d", &sum[rt]); 18 return; 19 } 20 int mid = (l + r) >> 1; 21 build(lson); 22 build(rson); 23 push_up(rt);//向上更新节点 24 } 25 26 //单点更新 27 void updata(int p, int add, int l, int r, int rt){//在p点增加add 28 if(l == r){//找到p点 29 sum[rt] += add;//单点更新 30 return; 31 } 32 int mid = (l + r) >> 1; 33 if(p <= mid) updata(p, add, lson); 34 else updata(p, add, rson); 35 push_up(rt);//向上更新节点 36 } 37 38 //区间求和 39 int query(int L, int R, int l, int r, int rt){//对[L, R]区间求和 40 if(L <= l && R >= r) return sum[rt];//当前区间[l, r]包含在求和区间[L, R]中 41 int ans = 0; 42 int mid = (l + r) >> 1; 43 if(L <= mid) ans += query(L, R, lson);//L在mid左边 44 if(R > mid) ans += query(L, R, rson);//R在mid右边 45 return ans; 46 } 47 48 int main(void){ 49 int t, n; 50 scanf("%d", &t); 51 for(int i = 1; i <= t; i++){ 52 printf("Case %d:\n", i); 53 scanf("%d", &n); 54 build(1, n, 1); 55 char s[7]; 56 while(scanf("%s", s) && s[0] != 'E'){ 57 int x, y; 58 scanf("%d%d", &x, &y); 59 if(s[0] == 'Q') printf("%d\n", query(x, y, 1, n, 1)); 60 else if(s[0] == 'A') updata(x, y, 1, n, 1); 61 else updata(x, -y, 1, n, 1); 62 } 63 } 64 return 0; 65 }
我就是我,颜色不一样的烟火 --- geloutingyu