敌兵布阵(线段树+单点更新)

匿名 (未验证) 提交于 2019-12-03 00:22:01


       这道题算是线段树的入门题了,线段树理解的话其实是挺好理解的,但写的话就感觉挺不好写的,毕竟有好几十行代码,讲解的话看下别人的博客,他们讲的我觉得很清楚了,然后如果觉得我的代码风格跟你差不多的,能接受我的这种写法的话,有什么不懂得可以问我。


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; }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!