zkw线段树

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<ctime>
using namespace std;
const int N=200005;
int n,bit,q;
long long sum[N<<2],mn[N<<2],mx[N<<2],add[N<<2];
long long max(long long a,long long b){
	return a>b?a:b;
}
long long min(long long a,long long b){
	return a<b?a:b;
}
void build(){
    for(bit=1;bit<=n;bit<<=1);
    for(int i=bit+1;i<=bit+n;i++){
		scanf("%lld",&mx[i]);
        sum[i]=mn[i]=mx[i];
	}
    for(int i=bit-1;i;i--){
        sum[i]=sum[i<<1]+sum[i<<1|1];
        mn[i]=min(mn[i<<1],mn[i<<1|1]),
        mn[i<<1]-=mn[i],mn[i<<1|1]-=mn[i];
        mx[i]=max(mx[i<<1],mx[i<<1|1]),
        mx[i<<1]-=mx[i],mx[i<<1|1]-=mx[i];
    }
}
void update_node(int x,int val){
    int a;
    mx[x+bit]+=val,mn[x+bit]+=val;
    for(x=x+bit;x;x>>=1){
		sum[x]+=val;
        a=max(mx[x<<1],mx[x<<1|1]),mx[x<<1]-=a,mx[x<<1|1]-=a,mx[x]+=a;
        a=min(mn[x<<1],mn[x<<1|1]),mn[x<<1]-=a,mn[x<<1|1]-=a,mn[x]+=a;
    }
}
void update_RMQ(int s,int t,int val){
	int a;
	if(s==t){
		update_node(s,val);
		return ;
	}
	mx[s+bit]+=val,mn[s+bit]+=val;
	mx[t+bit]+=val,mn[t+bit]+=val;
	for(s=s+bit,t=t+bit;s^t^1;s>>=1,t>>=1){
		if(~s&1){
			mx[s^1]+=val,mn[s^1]+=val;
		}
		if(t&1){
			mx[t^1]+=val,mn[t^1]+=val;
		}
		a=max(mx[s<<1],mx[s<<1|1]),mx[s<<1]-=a,mx[s<<1|1]-=a,mx[s]+=a;
		a=min(mn[s<<1],mn[s<<1|1]),mn[s<<1]-=a,mn[s<<1|1]-=a,mn[s]+=a;
		a=max(mx[t<<1],mx[t<<1|1]),mx[t<<1]-=a,mx[t<<1|1]-=a,mx[t]+=a;
		a=min(mn[t<<1],mn[t<<1|1]),mn[t<<1]-=a,mn[t<<1|1]-=a,mn[t]+=a;
	}
	a=max(mx[t<<1],mx[t<<1|1]),mx[t<<1]-=a,mx[t<<1|1]-=a,mx[t]+=a;
	a=min(mn[t<<1],mn[t<<1|1]),mn[t<<1]-=a,mn[t<<1|1]-=a,mn[t]+=a;
	for(;s;s>>=1){
		a=max(mx[s<<1],mx[s<<1|1]),mx[s<<1]-=a,mx[s<<1|1]-=a,mx[s]+=a;
		a=min(mn[s<<1],mn[s<<1|1]),mn[s<<1]-=a,mn[s<<1|1]-=a,mn[s]+=a;
	}
}
void update_sum(int s,int t,long long val){
    long long lc=0,rc=0,len=1;
    for(s=bit+s-1,t=bit+t+1;s^t^1;s>>=1,t>>=1,len<<=1){
        sum[s]+=val*lc;
        sum[t]+=val*rc;
        if(~s&1){
            add[s^1]+=val,sum[s^1]+=val*len,lc+=len;
		}
        if(t&1){
            add[t^1]+=val,sum[t^1]+=val*len,rc+=len;
		}
    }
    for(;s||t;s>>=1,t>>=1){
        sum[s]+=val*lc,sum[t]+=val*rc;
	}
}
long long query_RMQ_node(int x,long long ans=0){
    for(x+=bit;x;x>>=1){
		ans+=mn[x];
	}
	return ans;
}
long long query_sum_node(int x,long long ans=0){
	for(;x;x>>=1){
		ans+=sum[x];
	}
	return ans;
}
long long query_sum(int s,int t){
    int lc=0,rc=0,len=1;
    long long ans=0;
	if(s==t){
		query_sum_node(s);
	}
    for(s=bit+s-1,t=bit+t+1;s^t^1;s>>=1,t>>=1,len<<=1){
        if(add[s]){
			ans+=add[s]*lc;
		}
        if(add[t]){
			ans+=add[t]*rc;
		}
        if(~s&1){
            ans+=sum[s^1],lc+=len;
		}
        if(t&1)
            ans+=sum[t^1],rc+=len;
    }
    for (;s||t;s>>=1,t>>=1){
        ans+=add[s]*lc;
		ans+=add[t]*rc;
	}
    return ans; 
}
long long query_min(int s,int t,int L=0,int R=0,long long ans=0){
    if(s==t){
		query_RMQ_node(s);
	}
    for(s+=bit,t+=bit;s^t^1;s>>=1,t>>=1){
        L+=mn[s],R+=mn[t];
        if(~s&1){
			L=min(L,mn[s^1]);
		}
        if(t&1){
			R=min(R,mn[t^1]);
		}
    }
	L+=mn[s],R+=mn[t];
    for(ans=min(L,R),s>>=1;s;s>>=1){
		ans+=mn[s];
	}
    return ans;
}
long long query_max(int s,int t,int L=0,int R=0,long long ans=0){
    if(s==t){
		query_RMQ_node(s);
	}
    for(s+=bit,t+=bit;s^t^1;s>>=1,t>>=1){
        L+=mx[s],R+=mx[t];
        if(~s&1){
			L=max(L,mx[s^1]);
		}
        if(t&1){
			R=max(R,mx[t^1]);
		}
    }
	L+=mx[s],R+=mx[t];
    for(ans=max(L,R),s>>=1;s;s>>=1){
		ans+=mx[s];
	}
    return ans;
}
int main(){
    int opt,x,y,k;
	scanf("%d%d",&n,&q);
	build();
	for(int i=1;i<=q;i++){
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d%d",&x,&y,&k);
			update_sum(x,y,k);
		}
		else if(opt==2){
			scanf("%d%d",&x,&y);
			printf("%lld\n",query_sum(x,y));
		}
	}
    return 0;
}
posted @ 2019-07-18 14:06  prestige  阅读(110)  评论(0编辑  收藏  举报