MnZn求调连样例都过不去的线段树板子
查看原帖
MnZn求调连样例都过不去的线段树板子
560342
wjj255楼主2023/8/1 16:05

RT,调了一下午了,救救孩子吧QwQ

//P3372
#include<iostream>
using namespace std;
#define lc k<<1
#define rc k<<1|1
const int N=1e5+5;
int n,m,a[N];
struct node{
	int l,r,sum,add;
}tree[N*4];
void bulid(int k,int l,int r)
{
	tree[k].l=l;
	tree[k].r=r;
	if(l==r){
		tree[k].sum=a[l];
		return;
	}
	int mid=(l+r)/2;
	bulid(lc,l,mid);
	bulid(rc,mid+1,r);
	tree[k].sum=tree[lc].sum+tree[rc].sum;
}//建树 
void update(int k,int l,int r,int z)
{
	if(tree[k].l>=l&&tree[k].r<=r){
		tree[k].sum+=(r-l+1)*z;
		tree[k].add+=z;
		return;
	}
	int mid=(tree[k].l+tree[k].r)/2;
	if(tree[k].add){
		tree[lc].sum+=tree[k].add;
		tree[rc].sum+=tree[k].add;
		tree[lc].add+=tree[k].add;
		tree[rc].add+=tree[k].add;
		tree[k].add=0;
	}
	if(l<=mid)update(lc,l,r,z);
	if(r>mid)update(rc,l,r,z);
	tree[k].sum=tree[lc].sum+tree[rc].sum;
}//更新 
int query(int k,int l,int r)
{
	if(tree[k].l>=l&&tree[k].r<=r){
		return tree[k].sum;
	}
	int mid=(tree[k].l+tree[k].r)/2;
	int s=0;
	if(l<=mid)s+=query(lc,l,r);
	if(r>mid)s+=query(rc,l,r);
	return s;
}//查询 
int main()
{
	ios::sync_with_stdio(false);
	//freopen("xds1.in","r",stdin);
	int x,y,z,op;
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	bulid(1,1,n);
	for(int i=1;i<=m;i++){
		cin>>op>>x>>y;
		if(op==1){
			cin>>z;
			update(1,x,y,z);
		}
		else{
			cout<<query(1,x,y)<<endl;
		}
	}
	return 0;
 } 
2023/8/1 16:05
加载中...