线段树1

陈子骏

2018-04-02 17:48:28

Personal

``` #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; int n,m; int x,y,k; int v[500001],Lazy[500001]; long long s[1000001]; void pushdown(int o,int left,int right) { if(!Lazy[o])return; int mid=(right+left)>>1; if(left==right)return; s[o<<1]+=Lazy[o]*(mid-left+1); Lazy[o<<1]+=Lazy[o]; s[o<<1|1]+=Lazy[o]*(right-mid); Lazy[o<<1|1]+=Lazy[o]; Lazy[o]=0; } long long search(int o,int left,int right) { pushdown(o,left,right); if(x<=left&&y>=right)return s[o]; long long sum=0; int mid=(left+right)>>1; if(x<=mid) sum+=search(o<<1,left,mid); if(y>mid) sum+=search(o<<1|1,mid+1,right); return sum; } void change(int o,int left,int right) { pushdown(o,left,right); if(x<=left&&y>=right) { s[o]+=k*(right-left+1); Lazy[o]=k; return; } int mid=(left+right)>>1; if(x<=mid)change(o<<1,left,mid); if(y>mid)change(o<<1|1,mid+1,right); s[o]=s[o<<1]+s[o<<1|1]; } void build(int o,int left,int right) { if(left==right){ s[o]=v[left]; return; } int mid=(left+right)>>1; build(o<<1,left,mid); build(o<<1|1,mid+1,right); s[o]=s[o<<1]+s[o<<1|1]; } int main() { int a; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&v[i]); } build(1,1,n); for(int i=1;i<=m;i++) { scanf("%d",&a); if(a==1) { scanf("%d%d%d",&x,&y,&k); change(1,1,n); } if(a==2) { scanf("%d%d",&x,&y); printf("%lld\n",search(1,1,n)); } } return 0; } ```