P2357 守墓人

Aimee

这么个线段树版子还要解释

#include<iostream>
#include<cstdio>
#include<cstring> 
#include<algorithm>
#define int long long
using namespace std;
int n,m;
int f,x,y,k;
int tree[800001];
int lazy[800001];
void pushdown(int R,int l,int r){
	if(lazy[R]){
		lazy[R<<1]+=lazy[R];
		lazy[R<<1|1]+=lazy[R];
		int mid= (l+r)>>1;
		tree[R<<1]+=lazy[R]*(mid-l+1);
		tree[R<<1|1]+=lazy[R]*(r-mid);
		lazy[R]=0;
	}
}
void pushup(int r){
	tree[r]=tree[r<<1]+tree[r<<1|1]; 
}
void add(int root,int L,int R,int l,int r,int v){
	if(l<=L&&r>=R){
		lazy[root]+=v;
		tree[root]+=(R-L+1)*v;
		return ;
	}
	pushdown(root,L,R);
	int mid=(L+R)>>1;
	if(l<=mid) add(root<<1,L,mid,l,r,v);
	if(r>mid) add(root<<1|1,mid+1,R,l,r,v);
	pushup(root);
}
int query(int root,int L,int R,int l,int r){
	if(l<=L&&r>=R){
		return tree[root];
	}
	int mid=(L+R)>>1,ans=0;
	pushdown(root,L,R);
		if(l<=mid) ans+=query(root<<1,L,mid,l,r);
		if(r>mid) ans+=query(root<<1|1,mid+1,R,l,r);
		return ans;
}
signed main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%d",&x);
		add(1,1,n,i,i,x);
	}
	for(int i=1;i<=m;++i){
		scanf("%d",&f);
		if(f==1){
			scanf("%d%d%lld",&x,&y,&k);
			add(1,1,n,x,y,k);
		}
		if(f==2){
			scanf("%d",&x);
			add(1,1,n,1,1,x); 
		}
		if(f==3){
			scanf("%d",&x);
			add(1,1,n,1,1,-x);
		}
		if(f==4){
			scanf("%d%d",&x,&y);
			cout<<query(1,1,n,x,y)<<endl;
		}
		if(f==5){
			cout<<query(1,1,n,1,1)<<endl;
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/For-Miku/p/14427050.html