首页 > 其他 > 详细

线段树1(区间懒标记) 洛谷3372

时间:2018-08-05 10:51:58      阅读:131      评论:0      收藏:0      [点我收藏+]

感动,,我这个菜鸟把困扰多时的线段树干掉了(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

原文:https://www.cnblogs.com/asdic/p/9424719.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!