动态开点线段树求调
查看原帖
动态开点线段树求调
229957
Wu_while楼主2021/10/9 16:50

想要练习一下动态开点,然而挂了……

#include<iostream>
#include<cstdio>
#define MAXN 100010
using namespace std;
struct node
{
	int vis;
	int mul;
	int plus;
	int lson,rson;
}
t[MAXN<<1];
int n,m,MOD,tot,root;
int a[MAXN];
void push_up(int p)
{
	t[p].vis=t[t[p].lson].vis+t[t[p].rson].vis;
	t[p].vis%=MOD;
}
void build(int &p,int l,int r)
{
	if(!p)
		p=++tot;
	t[p].plus=0;
	t[p].mul=1;
	if(l==r)
	{
		t[p].vis=a[l]%MOD;
		return;
	}
	int mid=(l+r)>>1;
	build(t[p].lson,l,mid);
	build(t[p].rson,mid+1,r);
	push_up(p);
}
void push_tag(int &p,int l,int r,int m,int k)
{
	if(!p)
	{
		p=++tot;
		t[p].mul=1;
		t[p].plus=0;
	}
	t[p].vis*=m;
	t[p].vis%=MOD;
	t[p].vis+=(r-l+1)*k%MOD;
	t[p].vis%=MOD;
	t[p].mul*=m;
	t[p].mul%=MOD;
	t[p].plus*=m;
	t[p].plus%=MOD;
	t[p].plus+=k;
	t[p].plus%=MOD;
}
void push_down(int p,int l,int r)
{
	int mid=(l+r)>>1;
	push_tag(t[p].lson,l,mid,t[p].mul,t[p].plus);
	push_tag(t[p].rson,mid+1,r,t[p].mul,t[p].plus);
	t[p].plus=0;
	t[p].mul=1;
}
void update_plus(int &p,int l,int r,int L,int R,int k)
{
	if(!p)
	{
		p=++tot;
		t[p].mul=1;
	}
	if(L<=l&&R>=r)
	{
		push_tag(p,l,r,1,k);
		return;
	}
	int mid=(l+r)>>1;
	push_down(p,l,r);
	if(L<=mid);
		update_plus(t[p].lson,l,mid,L,R,k);
	if(R>=mid+1);
		update_plus(t[p].rson,mid+1,r,L,R,k);
	push_up(p);
}
void update_mul(int &p,int l,int r,int L,int R,int k)
{
	if(!p)
	{
		p=++tot;
		t[p].mul=1;
	}
	if(L<=l&&R>=r)
	{
		push_tag(p,l,r,k,0);
		return;
	}
	int mid=(l+r)>>1;
	push_down(p,l,r);
	if(L<=mid)
		update_mul(t[p].lson,l,mid,L,R,k);
	if(R>=mid+1)
		update_mul(t[p].rson,mid+1,r,L,R,k);
	push_up(p);
}
int query(int p,int l,int r,int L,int R)
{
	if(L<=l&&R>=r)
		return t[p].vis%MOD;
	int mid=(l+r)>>1;
	int res=0;
	push_down(p,l,r);
	if(L<=mid)
		res+=query(t[p].lson,l,mid,L,R);
	if(R>=mid+1)
		res+=query(t[p].rson,mid+1,r,L,R);
	return res%MOD;
}
int main()
{
	scanf("%lld%lld%lld",&n,&m,&MOD);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	build(root,1,n);
	for(int i=1;i<=m;i++)
	{
		int op,x,y,k;
		scanf("%lld",&op);
		if(op==1)
		{
			scanf("%lld%lld%lld",&x,&y,&k);
			update_mul(root,1,n,x,y,k);
		}
		else if(op==2)
		{
			scanf("%lld%lld%lld",&x,&y,&k);
			update_plus(root,1,n,x,y,k);
		}
		else
		{
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",query(root,1,n,x,y));
		}
	}
	return 0;
 } 
2021/10/9 16:50
加载中...