线段树区改区查标记永久化板子

打一次错一次qvq

#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;

inline void input(int &x){
    int ans=0,f=1;
    char c=getchar();
    while(c>'9'||c<'0'){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        ans=ans*10+c-48;
        c=getchar();
    }
    x=ans*f;
}

inline void output(int x){
    if(x<0)x=-x,putchar('-');
    if(x>9)output(x/10);
    putchar(x%10+48);
}

inline void writeln(int x){
    output(x);
    putchar('
');
}

int n,m,a[100005],c[400005],addsum[400005];

inline void build(int k,int l,int r){
	if(l==r){
		c[k]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	c[k]=c[k<<1]+c[k<<1|1];
}

inline void fix(int k,int l,int r,int xl,int xr,int x){
	if(xl<=l&&r<=xr){//顺序 
		addsum[k]+=x;
		return;
	}
	int mid=(l+r)>>1;
	if(xl<=mid)fix(k<<1,l,mid,xl,xr,x);
	if(xr>=mid+1)fix(k<<1|1,mid+1,r,xl,xr,x);
	c[k]+=(min(xr,r)-max(xl,l)+1)*x;//+1
}

inline int query(int k,int l,int r,int xl,int xr){
	if(xl<=l&&r<=xr){
		return c[k]+(min(xr,r)-max(xl,l)+1)*addsum[k];
	}
	int mid=(l+r)>>1,ans=(min(xr,r)-max(xl,l)+1)*addsum[k];
	if(xl<=mid)ans+=query(k<<1,l,mid,xl,xr);
	if(xr>=mid+1)ans+=query(k<<1|1,mid+1,r,xl,xr);
	return ans;
}

signed main(){
	input(n);input(m);
	for(int i=1;i<=n;i++)input(a[i]);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt,x,y,k;
		input(opt);
		if(opt==1){
			input(x);input(y);input(k);
			fix(1,1,n,x,y,k);
		}
		else{
			input(x);input(y);
			writeln(query(1,1,n,x,y));
		}
	}
} 
原文地址:https://www.cnblogs.com/Y15BeTa/p/11400178.html