【洛谷】P3372线段树1 线段树模板

来源:互联网 发布:写作的软件 编辑:程序博客网 时间:2024/06/01 10:42
#include <cstdio>#define C (c=getchar())#define LL long longusing namespace std;LL lz[262845];LL tr[262845];LL a[100005];LL m,n,x,y,k,w;inline void read(LL &n){LL f=1;char c;n=0;C;while (c<'0'||c>'9') c=='-'?f=-1,C:C;while (c>='0'&&c<='9') n=(n<<3)+(n<<1)+c-48,C;n*=f;return;}void tag_down(LL q,LL L,LL R){if (lz[q]!=0){LL md=(L+R)/2;lz[2*q]+=lz[q];lz[2*q+1]+=lz[q];tr[2*q]+=(md-L+1)*lz[q];tr[2*q+1]+=(R-md)*lz[q];lz[q]=0;}return;}void bt(LL q,LL l,LL r){if (l==r){tr[q]=a[l];return;}bt(2*q,l,(l+r)/2);bt(2*q+1,(l+r)/2+1,r);tr[q]=tr[2*q]+tr[2*q+1];return;}void add(LL q,LL l,LL r,LL L,LL R){if (l==L&&r==R){if (L!=R) lz[q]+=k;tr[q]+=k*(r-l+1);return;}LL mid=(L+R)/2;if (r<=mid){tr[q]+=(r-l+1)*k;add(2*q,l,r,L,mid);}elseif (l>=mid+1){tr[q]+=(r-l+1)*k;add(2*q+1,l,r,mid+1,R);}else{tr[q]+=(r-l+1)*k;add(2*q,l,mid,L,mid);add(2*q+1,mid+1,r,mid+1,R);}return;}LL find(LL q,LL l,LL r,LL L,LL R){if (l==L&&r==R) return tr[q];LL mid=(L+R)/2;tag_down(q,L,R);if (r<=mid){return find(2*q,l,r,L,mid);}elseif (l>=mid+1){return find(2*q+1,l,r,mid+1,R);}else{return find(2*q,l,mid,L,mid)+find(2*q+1,mid+1,r,mid+1,R);}}int main(void){read(n),read(m);for (register LL i=1;i<=n;++i){read(a[i]);}bt(1,1,n);for (register LL i=1;i<=m;++i){read(w);if (w==1){read(x),read(y),read(k);add(1,x,y,1,n);}elseif (w==2){read(x),read(y);printf("%lld\n",find(1,x,y,1,n));}}return 0;}

原创粉丝点击