30分求助线段树
查看原帖
30分求助线段树
308854
tzl_Dedicatus545楼主2021/8/14 19:24

RT,一直 RERE

//By: Luogu@wangdemao(308854)
#include <bits/stdc++.h>
#define ull unsigned long long
#define int long long

using namespace std;

const int INF=0x3f3f3f3f;
int h[400005];

struct Node
{
	int Tag1=1,Tag2=0,Sum=0;
}a[400005];
int n,m,p;

int lc(int u)
{
	return u<<1;
}
int rc(int u)
{
	return (u<<1)+1;
}

void PushUp(int u)
{
	a[u].Sum=(a[lc(u)].Sum+a[rc(u)].Sum)%p;
}

void BuildTree(int u,int l,int r)
{
	if(l==r)
	{
		a[u].Sum=h[l]%p;
		
		return ;
	}
	
	int mid=(l+r)/2;
	
	BuildTree(lc(u),l,mid);
	BuildTree(rc(u),mid+1,r);
	
	PushUp(u);
}

void MoveTag(int u,int l,int r,int val1,int val2)
{
	a[u].Sum=(a[u].Sum*val1)%p;
	a[u].Sum=(a[u].Sum+((r-l+1)*val2)%p)%p;
	
	a[u].Tag1*=val1;
	a[u].Tag1%=p;
	a[u].Tag2+=val2;
	a[u].Tag2%=p;
}

void PushDown(int u,int l,int r)
{
	int mid=(l+r)/2;
	
	MoveTag(lc(u),l,mid,a[u].Tag1,a[u].Tag2);
	MoveTag(rc(u),mid+1,r,a[u].Tag1,a[u].Tag2);
	
	a[u].Tag1=1;
	a[u].Tag2=0;
}

int QuerySum(int u,int l,int r,int ql,int qr)
{
	if(ql<=l && r<=qr)
	{
		return a[u].Sum;
	}
	
	PushDown(u,l,r);
	
	int mid=(l+r)/2;
	int ans=0;
	
	if(ql<=mid)
		ans+=QuerySum(lc(u),l,mid,ql,qr)%p;
	if(qr>mid)
		ans+=QuerySum(rc(u),mid+1,r,ql,qr)%p;
	
	return ans%p;
}

void QueryAdd(int u,int l,int r,int ql,int qr,int val)
{
	if(ql<=l && r<=qr)
	{
		PushDown(u,l,r);
		
		a[u].Sum+=val*(r-l+1)%p;
		a[u].Tag2+=val;
		a[u].Tag2%=p;
		
		a[u].Sum%=p;

		return ;
	}
	
	PushDown(u,l,r);
	
	int mid=(l+r)/2;
	
	if(ql<=mid)
		QueryAdd(lc(u),l,mid,ql,qr,val);
	if(qr>mid)
		QueryAdd(rc(u),mid+1,r,ql,qr,val);
		
	PushUp(u);
	
	return ;
}

void QueryProduct(int u,int l,int r,int ql,int qr,int val)
{
	if(ql<=l && r<=qr)
	{
		//PushDown(u,l,r); 
		a[u].Sum*=val;
		a[u].Sum%=p;
		
		a[u].Tag1*=val;
		a[u].Tag1%=p;
		
		a[u].Tag2*=val;
		a[u].Tag2%=p;
		
		PushDown(u,l,r); 
		
		return ;
	}
	
	PushDown(u,l,r); 
	
	int mid=(l+r)/2;
	
	if(ql<=mid)
		QueryProduct(lc(u),l,mid,ql,qr,val);
	if(qr>mid)
		QueryProduct(rc(u),mid+1,r,ql,qr,val);
		
	PushUp(u);
	
	return ;	
}

signed main()
{
	cin>>n>>m>>p;
	
	for(int i=1;i<=n;i++)
		cin>>h[i];
	
	BuildTree(1,1,n);
	
	while(m--)
	{
		int Code,x,y,k;
		
		cin>>Code>>x>>y;
		
		if(Code==1)
		{
			cin>>k;
			
			QueryProduct(1,1,n,x,y,k);
		}
		
		if(Code==2)
		{
			cin>>k;
			
			QueryAdd(1,1,n,x,y,k);
		}
		
		if(Code==3)
			cout<<QuerySum(1,1,n,x,y)%p<<endl;
	}
	
	return 0;
}
2021/8/14 19:24
加载中...