线段树单点更新,模板题,Add和Sub利用单点更新。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define scd(a) scanf("%d",&a) #define scs(a) scanf("%s",a) #define nsc(a,b) scanf("%d %d",&a,&b) #define pr(a) printf("%d\n",a) #define lson l,mid,rt<<1 //根的左孩子 #define rson mid+1,r,rt<<1|1 //右孩子 #define ll long long const int maxn=5e4+20; int sto[maxn<<2]; void PushUp(int rt) { sto[rt]=sto[rt<<1]+sto[rt<<1|1]; } void BuildTree(int l,int r,int rt) //建树 { if(l==r) { scd(sto[rt]); return ; } int mid=(l+r)>>1; BuildTree(lson); BuildTree(rson); PushUp(rt); } void update(int p,int v,int l,int r,int rt) //更新sto数组的值 { if(l==r) { sto[rt]+=v; return ; } int mid=(r+l)>>1; if(p<=mid) update(p,v,lson); else update(p,v,rson); PushUp(rt); } int query(int L,int R,int l,int r,int rt) { if(L<=l&&R>=r) { return sto[rt]; } int res=0; int mid=(r+l)>>1; if(L<=mid) res+=query(L,R,lson); if(R>mid) res+=query(L,R,rson); return res; } int main() { char str[8]; int t,n,a,b; scd(t); for(int i=1; i<=t; i++) { scd(n); BuildTree(1,n,1); printf("Case %d:\n",i); scs(str); while(strcmp(str,"End")) { nsc(a,b); if(!strcmp(str,"Add")) { update(a,b,1,n,1); } else if(!strcmp(str,"Sub")) { update(a,-b,1,n,1); } else { pr(query(a,b,1,n,1)); } scs(str); } } return 0; } 初学线段树,感觉单点更新和区间更新还是不太容易理解,仅仅套模板很难学会。
