第一次打动态开点,求助
查看原帖
第一次打动态开点,求助
903851
Empty_Sky楼主2023/5/21 15:09

(也许错得很离谱)

#include<bits/stdc++.h>
using namespace std;

#define LL long long

const int N=1e5+1;

int n,m;

int rt,tot;
struct Node{
	int l,r;
	LL add,sum;
} tr[N<<1];

inline void create(int &u)
{
	if(!u) u=++tot;
}

inline void push_up(int u)
{
	tr[u].sum=tr[tr[u].l].sum+tr[tr[u].r].sum;
}

inline void push_down(int u,int l,int r,int mid)
{
	if(tr[u].add)
	{
		tr[tr[u].l].sum+=tr[tr[u].l].add*(mid-l+1),
		tr[tr[u].l].add+=tr[u].add;
		
		tr[tr[u].r].sum+=tr[tr[u].r].add*(r-mid);
		tr[tr[u].r].add+=tr[u].add;
		
		tr[u].add=0;
	}
}

void insert(int u,int l,int r,int p,int x)
{
	create(u);
	
	if(l==r) tr[u].sum=x;
	else
	{
		int mid=l+r>>1;
		if(p<=mid) insert(tr[u].l,l,mid,p,x);
		else insert(tr[u].r,mid+1,r,p,x);
		
		push_up(u);
	}
}

void update(int u,int l,int r,int ul,int ur,int x)
{
	create(u);
	
	if(l>=ul&&r<=ur)
	{
		tr[u].sum+=(LL)x*(r-l+1);
		tr[u].add+=x;
	}
	else
	{
		int mid=l+r>>1;
		push_down(u,l,r,mid);
		
		if(ul<=mid) update(tr[u].l,l,mid,ul,ur,x);
		if(ur>mid) update(tr[u].r,mid+1,r,ul,ur,x);
		
		push_up(u);
	}
}

LL query(int u,int l,int r,int ql,int qr)
{
	create(u);
	
	if(l>=ql&&r<=qr) return tr[u].sum;
	
	int mid=l+r>>1;
	push_down(u,l,r,mid);
	
	LL res=0;
	if(ql<=mid) res+=query(tr[u].l,l,mid,ql,qr);
	if(qr>mid) res+=query(tr[u].r,mid+1,r,ql,qr);
	
	return res;
}

int main()
{
	scanf("%d%d",&n,&m);
	
	int t;
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&t);
		insert(rt,1,n,i,t);
	}
	
	int op,x,y,k;
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d%d",&op,&x,&y);
		if(op==1)
		{
			scanf("%d",&k);
			update(rt,1,n,x,y,k);
		}
		else printf("%lld\n",query(rt,1,n,x,y));
	}
	
	return 0;
}
2023/5/21 15:09
加载中...