1. 程式人生 > >線段樹1(區間懶標記) 洛谷3372

線段樹1(區間懶標記) 洛谷3372

+= char mes div fin bits down ++ space

感動,,我這個菜鳥把困擾多時的線段樹幹掉了(wanna cry),留給日後作紀念

#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
typedef long long ll;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==-)f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1
)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int maxn=100500; ll a[maxn]; ll sum[maxn<<2],tag[maxn<<2]; ll n,m; ll SUM; void pushup(int k){ sum[k]=sum[k<<1]+sum[k<<1|1];} void pushdown(int k,int l,int r,int mid){ if(!tag[k]) return; int v=tag[k]; tag[k
<<1]+=v;sum[k<<1]+=(mid-l+1)*v; tag[k<<1|1]+=v;sum[k<<1|1]+=(r-mid)*v; tag[k]=0; } void update(int k,int l,int r,int x,int y,int v){ if(x<=l&&r<=y){sum[k]+=v*(r-l+1);tag[k]+=v;return;} int mid=(l+r)>>1; pushdown(k,l,r,mid); if(x<=mid) update(k<<1
,l,mid,x,y,v); if(mid<y) update(k<<1|1,mid+1,r,x,y,v); pushup(k); } void build(int k,int l,int r){ if(l==r){sum[k]=a[l];return;} int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); pushup(k); } void query(int k,int l,int r,int x,int y){ if(x<=l&&r<=y){SUM+=sum[k];return;} int mid=(l+r)>>1; pushdown(k,l,r,mid); if(x<=mid) query(k<<1,l,mid,x,y); if(mid<y) query(k<<1|1,mid+1,r,x,y); } int main(){ n=(ll)read(),m=(ll)read(); rep(i,1,n) a[i]=read(); build(1,1,n); rep(i,1,m){ int t=read(),x,y,k; if(t==1){ x=read(),y=read(),k=read(); update(1,1,n,x,y,k); }else if(t==2){ x=read(),y=read(); SUM=0; query(1,1,n,x,y); printf("%lld\n",SUM); } } return 0; }

線段樹1(區間懶標記) 洛谷3372