线段树模板
单点更新(HDU1166)
#include <cstdio> #include <iostream> using namespace std; const int MAXN=2e5+10; const int MAXNODE=MAXN<<2;//一般开到4倍 int sum; struct node { int l; int r; int value; }tree[MAXNODE]; int father[MAXN];//用来储存第x个元素在线段数的结点位置 void BuildTree(int i,int l,int r) { tree[i].l=l; tree[i].r=r; tree[i].value=0; if(l==r) { father[l]=i; return; } BuildTree(i<<1,l,(l+r)/2); BuildTree((i<<1)+1,(l+r)/2+1,r); } void UpTree(int ri) { if(ri==1) return; int fi=ri/2; int a=tree[fi<<1].value; int b=tree[(fi<<1)+1].value; tree[fi].value=a+b; UpTree(fi); } int MAX; void Query(int i,int l,int r) { if(tree[i].l==l&&tree[i].r==r) { sum+=tree[i].value; return; } i=i<<1; if(l<=tree[i].r) { if(r<=tree[i].r) Query(i,l,r); else Query(i,l,tree[i].r); } i++; if(r>=tree[i].l) { if(l>=tree[i].l)Query(i,l,r); else Query(i,tree[i].l,r); } } int main() { int n,m,g,a,b,t; char ch[100]; scanf("%d",&t); for(int k=1;k<=t;k++) { scanf("%d",&n); BuildTree(1,1,n); for(int i=1;i<=n;i++) { scanf("%d",&g); tree[father[i]].value=g; UpTree(father[i]); } printf("Case %d:\n",k); while(scanf(" %s",ch)!=EOF) { sum=0; if(ch[0]=='E') break; scanf("%d%d",&a,&b); if(ch[0]=='Q') { Query(1,a,b); printf("%d\n",sum); } else if(ch[0]=='A') { tree[father[a]].value+=b; UpTree(father[a]); } else if(ch[0]=='S') { tree[father[a]].value-=b; UpTree(father[a]); } } } return 0; }
区间更新(HDU1698)
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int MAXN=1e5+100; typedef long long ll; int sum[MAXN<<2]; int add[MAXN<<2]; int res; struct node { int l; int r; }tree[MAXN<<2]; void PushUp(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void PushDown(int rt,int m) { if(add[rt]) { add[rt<<1]=add[rt]; add[rt<<1|1]=add[rt]; sum[rt<<1]=add[rt]*(m-m/2); sum[rt<<1|1]=add[rt]*(m/2); add[rt]=0; } } void BuildTree(int l,int r,int rt) { tree[rt].l=l; tree[rt].r=r; add[rt]=0; if(l==r) { sum[rt]=1; return; } int mid=(tree[rt].l+tree[rt].r)/2; BuildTree(l,mid,rt<<1); BuildTree(mid+1,r,rt<<1|1); PushUp(rt); } void Update(int c,int l,int r,int rt) { if(tree[rt].l==l&&tree[rt].r==r) { sum[rt]=c*(r-l+1); add[rt]=c; return; } int mid=(tree[rt].l+tree[rt].r)/2; PushDown(rt,tree[rt].r-tree[rt].l+1); if(r<=mid) Update(c,l,r,rt<<1); else if(l>mid)Update(c,l,r,rt<<1|1); else { Update(c,l,mid,rt<<1); Update(c,mid+1,r,rt<<1|1); } PushUp(rt); } void Query(int l,int r,int rt) { if(tree[rt].l==l&&tree[rt].r==r) { res+=sum[rt]; return; } int mid=(tree[rt].l+tree[rt].r)/2; PushDown(rt,tree[rt].r-tree[rt].l+1); if(r<=mid)Query(l,r,rt<<1); else if(l>mid)Query(l,r,rt<<1|1); else { Query(l,mid,rt<<1); Query(mid+1,r,rt<<1|1); } PushUp(rt); } int main() { int t,n,q,a,b,c,Case; scanf("%d",&t); Case=0; while(t--) { Case++; scanf("%d",&n); BuildTree(1,n,1); scanf("%d",&q); while(q--) { scanf("%d%d%d",&a,&b,&c); Update(c,a,b,1); } res=0; Query(1,n,1); printf("Case %d: The total value of the hook is %d.\n",Case,res); } return 0; }