第一篇博客,就记一下十分优美的树状数组模板吧。

#include<cstdio> int n,t,a[1001],c[1001]; int lowbit(int bin){ return bin&(-bin); } void add(int x,int y){ for(int i=x;i<=n;i+=lowbit(i)) c[i]+=y; } int getsum(int x){ int ans=0; for(int i=x;i>0;i-=lowbit(i)) ans+=c[i]; return ans; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) add(i,a[i]); scanf("%d",&t); while(t--){ int l,r; scanf("%d%d",&l,&r); printf("%d\n",getsum(r)-getsum(l)); } return 0; }
还有差分树状数组。

#include<cstdio> int n,m; int arr[500005],dif[500005],tree[500005]; int lowbit(int k){ return k&(-k); } void add(int k,int x){ while(k<=n){ tree[k]+=x; k+=lowbit(k); } return; } int getarr(int k){ int ans=0; while(k){ ans+=tree[k]; k-=lowbit(k); } return ans; } int read(){ int x=0,w=1; char c=getchar(); while(c<'0'||c>'9'){ if(c=='-') w=-1; c=getchar(); } while(c>='0'&&c<='9'){ x=(x<<3)+(x<<1)+(c-'0'); c=getchar(); } return x*w; } int main(){ n=read(); m=read(); arr[0]=0; for(int i=1;i<=n;i++){ arr[i]=read(); dif[i]=arr[i]-arr[i-1]; add(i,dif[i]); } while(m--){ int x=read(); if(x==1){ int l=read(),r=read(),w=read(); add(l,w); add(r+1,-w); } if(x==2){ printf("%d\n",getarr(read())); } } return 0; }
还有我用py写的树状数组,不过放到洛谷上T了,情理之中的事。

# -*- coding: utf-8 -*- tree=[] a=[] n=0 m=0 def read_int(): """读入整数""" s=input() lst=s.split(' ') return lst def add(x,t): global tree while x<=n: tree[x]+=t x+=(x&(-x)) def get(x): ans=0 while x>0: ans+=tree[x] x-=(x&(-x)) return ans if __name__=="""__main__""": a=read_int() n=int(a[0]) m=int(a[1]) a=read_int() i=0 while i<=n: tree.append(0) i+=1 i=0 while i<n: add(i+1,int(a[i])) i+=1 while m>0: a=read_int() if int(a[0])==1: add(int(a[1]),int(a[2])) elif int(a[0])==2: print(get(int(a[2]))-get(int(a[1])-1)) m-=1
就这样了。