这道题算是线段树的入门题了,线段树理解的话其实是挺好理解的,但写的话就感觉挺不好写的,毕竟有好几十行代码,讲解的话看下别人的博客,他们讲的我觉得很清楚了,然后如果觉得我的代码风格跟你差不多的,能接受我的这种写法的话,有什么不懂得可以问我。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #define lson l, mid, o << 1 #define rson mid + 1, r, o << 1 | 1 #define maxn 50005 using namespace std; int sum[maxn << 2]; int T,n; string str; void Pushup(int o){ sum[o] = sum[o << 1] + sum[o << 1 | 1]; // 向上更新维护一个sum值 } void Build(int l, int r, int o){ if(l == r){ scanf("%d",&sum[o]); return ; } int mid = (l + r) >> 1; Build(lson); Build(rson); Pushup(o); } void Update(int x, int ans, int l, int r,int o){ if(l == r){ sum[o] += ans; return ; } int mid = (l + r) >> 1; if(x <= mid) Update(x, ans, lson); else Update(x, ans, rson); Pushup(o); } int Query(int L, int R, int l, int r, int o){ if(L <= l && r <= R){ return sum[o]; } int mid = (l + r) >> 1; int ans = 0; if(L <= mid) ans += Query(L, R, lson); if(R > mid) ans += Query(L, R, rson); return ans; } int main() { int Case = 1; scanf("%d",&T); while(T--){ scanf("%d",&n); Build(1,n,1); int a,b; printf("Case %d:\n",Case++); while(cin>>str){ if(str == "End")break; scanf("%d%d",&a,&b); if(str == "Add"){ Update(a,b,1,n,1); } else if(str == "Sub"){ Update(a,-b,1,n,1); } else{ printf("%d\n",Query(a,b,1,n,1)); } } } return 0; }
转载请标明出处:敌兵布阵(线段树+单点更新)
文章来源: 敌兵布阵(线段树+单点更新)