0.树状数组
常数极小,只能做前缀和,不过可以通过一些技巧让它做很多事情
比如,支持区间修改,区间查询:
#include<algorithm> #include<iostream> #include<cstdio> using namespace std; inline int rd(){ int ret=0,f=1;char c; while(c=getchar(),!isdigit(c))f=c=='-'?-1:1; while(isdigit(c))ret=ret*10+c-'0',c=getchar(); return ret*f; } const int MAXN = 100005; typedef long long ll; int n,m; int t1[MAXN],t2[MAXN]; int querys(int x){ int ret=0; for(int i=x;i;i-=i&-i)ret+=(x+1)*t1[i]-t2[i]; return ret; } int query(int l,int r){ return querys(r)-querys(l-1); } void updates(int x,int w){ for(int i=x;i<=n;i+=i&-i)t1[i]+=w,t2[i]+=x*w; } void update(int l,int r,int w){ updates(l,w);updates(r+1,-w); } int main(){ n=rd();m=rd(); int q,x,y,z; for(register int i=1;i<=n;i++)update(i,i,rd()); for(register int i=1;i<=m;i++){ q=rd();x=rd();y=rd(); if(q==1) z=rd(),update(x,y,z); else cout<<query(x,y)<<endl; } return 0; }