线段树求调
查看原帖
线段树求调
705570
lzj001楼主2023/3/18 13:44
#include<bits/stdc++.h>
#define ls (root<<1)
#define rs (root<<1|1)
#define mid ( l+r >> 1)
#define LL long long 
using namespace std;
const int MXN=1e5+5;
int a[MXN];
struct Tree{//cf乘法缓存,sum加法缓存,val值 
	LL cf,sum,val;
}tree[MXN];
int mod;
void date(int l,int r,int root)
{
	tree[root].val=(tree[l].val+tree[r].val)%mod;
	return;
}
void build_tree(int l,int r,int root)
{
//	if(l>r)return;
	if(l==r)
	{
		tree[root].cf=1;
		tree[root].val=a[l];
		return;
	}
	build_tree(l,mid,ls);
	build_tree(mid+1,r,rs);
	date(ls,rs,root);
	tree[root].cf=1;
}
void push_down(int l,int r,int root)
{
	if(tree[root].cf!=1)
	{
		tree[ls].cf=(tree[ls].cf*tree[root].cf)%mod;
		tree[rs].cf=(tree[rs].cf*tree[root].cf)%mod;
		tree[ls].sum=(tree[ls].sum*tree[root].cf)%mod;
		tree[rs].sum=(tree[rs].sum*tree[root].cf)%mod;
		tree[ls].val=(tree[ls].val*tree[root].cf)%mod;
		tree[rs].val=(tree[rs].val*tree[root].cf)%mod;
		tree[root].cf=1;
	}
	if(tree[root].sum)
	{
		tree[ls].sum=(tree[ls].sum+tree[root].sum)%mod;
		tree[rs].sum=(tree[rs].sum+tree[root].sum)%mod;
		tree[ls].val=(tree[ls].val+tree[root].sum*(mid-l+1))%mod;
		tree[rs].val=(tree[rs].val+tree[root].sum*(r-mid))%mod; 
		tree[root].sum=0;
	}
	return;
}
LL query(int l,int r,int L,int R,int root)
{
	if(r<L||l>R)return 0;
	if(L<=l&&R>=r)
	{
		return tree[root].val;
	}
	push_down(l,r,root);
	LL s1=query(l,mid,L,R,ls);
	LL s2=query(mid+1,r,L,R,rs);
	return (s1+s2)%mod;
}
void update(int l,int r,int L,int R,int root,int v,int flag)
{
	if(r<L||l>R)return;
	if(L<=l&&R>=r)
	{
		if(flag==1)
		{
			tree[root].val=(tree[root].val*v)%mod;
			tree[root].cf=(tree[root].cf*v)%mod;
			tree[root].sum=(tree[root].sum*v)%mod;
			return;
		}
		if(flag==2)
		{
		    tree[root].val=(tree[root].val+v*(r-l+1))%mod;
			tree[root].sum=(tree[root].sum+v)%mod;
			return;	
		}
		push_down(l,r,root);
		update(l,mid,L,R,ls,v,flag);
		update(mid+1,r,L,R,rs,v,flag);
		date(ls,rs,root);
	}
}
int main()
{
	int n,m,p;
	scanf("%d%d%d",&n,&m,&p);
	mod=p;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	build_tree(1,n,1);
	int flag=0;
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&flag);
		if(flag==1)
		{
			int x,y,k;
			scanf("%d%d%d",&x,&y,&k);
		
			update(1,n,x,y,1,k,flag);
		}
		if(flag==2)
		{
			int x,y,k;
			scanf("%d%d%d",&x,&y,&k);
			update(1,n,x,y,1,k,flag);
		}
		if(flag==3)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			cout<<query(1,n,x,y,1)<<endl;
		}
	 } 
	return 0;
}

2023/3/18 13:44
加载中...