30pts分块
查看原帖
30pts分块
943468
lizicheng3042楼主2023/12/3 17:35
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const ll M=998244353;
int n,m,tot,op,i,j;
ll k;
ll num[100005],kk;
struct node
{
	int l,r;
	ll sum,lazy,lazy2=1;
}kuai[100005];
void build()
{
	int u=sqrt(n);
	while(tot<u)
	{
		tot++;
		kuai[tot].l=1+u*(tot-1);
		kuai[tot].r=u*tot;
		for(int a=kuai[tot].l;a<=kuai[tot].r;a++)
			kuai[tot].sum+=num[a];
	}
	if(u*tot<n)
	{
		tot++;
		kuai[tot].l=u*(tot-1)+1;
		kuai[tot].r=n;
		for(int a=kuai[tot].l;a<=kuai[tot].r;a++)
			kuai[tot].sum+=num[a];		
	}
	kuai[++tot].l=n+1;
}
void pushdown(int w)
{
	ll b=kuai[w].lazy,c=kuai[w].lazy2;
	for(int a=kuai[w].l;a<=kuai[w].r;a++)
		num[a]=(num[a]*c+b)%kk;
	kuai[w].lazy=0;
	kuai[w].lazy2=1;
}
void update(int u,int K,int e)
{
	int c=1,pos=u;
	while(kuai[c].r<u)
	{
		c++;		
	}
	do
	{
		if(pos==kuai[c].l&&kuai[c].r<=K)
		{
			kuai[c].lazy+=e;
			kuai[c].lazy%=kk;
			kuai[c].sum+=(kuai[c].r-kuai[c].l+1)*e;
		}
		else if(kuai[c].r>K)
		{
			if(kuai[c].lazy2!=1)
				pushdown(c);
			kuai[c].sum+=(K-max(pos,kuai[c].l)+1)*e;
			for(int a=max(kuai[c].l,pos);a<=K;a++)
				num[a]+=e;
		}
		else
		{
			if(kuai[c].lazy2!=1)
				pushdown(c);
			kuai[c].sum+=(kuai[c].r-pos+1)*e;
			for(int a=pos;a<=kuai[c].r;a++)
				num[a]+=e;			
		}
//		
		c++;
		pos=kuai[c].l;
	}while(pos<=K);
}
void update2(int u,int K,ll e)
{
	int c=1,pos=u;
	while(kuai[c].r<u)
	{
		c++;		
	}
	do
	{
		if(pos==kuai[c].l&&kuai[c].r<=K)
		{
			kuai[c].lazy2*=e;
			kuai[c].lazy2%=kk;
			kuai[c].lazy*=e;
			kuai[c].lazy%=kk;
			kuai[c].sum=kuai[c].sum*e%kk;
		}
		else if(kuai[c].r>K)
		{
			if(kuai[c].lazy||kuai[c].lazy2!=1)
				pushdown(c);
			kuai[c].sum+=(K-max(pos,kuai[c].l)+1)*e;
			for(int a=max(kuai[c].l,pos);a<=K;a++)
			{
				kuai[c].sum=(kuai[c].sum+num[a]*(e-1))%kk;
				num[a]=num[a]*e%kk;				
			}
		}
		else
		{
			if(kuai[c].lazy||kuai[c].lazy2!=1)
				pushdown(c);
			for(int a=pos;a<=kuai[c].r;a++)
			{
				kuai[c].sum=(kuai[c].sum+num[a]*(e-1))%kk;
				num[a]=num[a]*e%kk;				
			}
			
		}
		c++;
		pos=kuai[c].l;
	}while(pos<=K);
}
ll query(int w,int a)
{
	ll o=0;
	int pos=w,c=1;
	while(kuai[c].r<w)
		c++;
	do
	{			
		if(pos==kuai[c].l&&kuai[c].r<=a)
		{
			o+=kuai[c].sum;
		}
		else if(kuai[c].r>a)
		{
			if(kuai[c].lazy||kuai[c].lazy2!=1)
				pushdown(c);
			for(int b=max(pos,kuai[c].l);b<=a;b++)
				o+=num[b];
		}
		else
		{
			if(kuai[c].lazy||kuai[c].lazy2!=1)
				pushdown(c);
			for(int b=pos;b<=kuai[c].r;b++)
				o+=num[b];			
		}
//		printf("(%d,%d,%d)",kuai[c].l,kuai[c].r,o);		
		c++;
		pos=kuai[c].l;
	}while(pos<=a);
	return o;
}
int main()
{
	scanf("%d%d%lld",&n,&m,&kk);
	for(int a=1;a<=n;a++)
	{
		scanf("%lld",&num[a]);
	}
	build();
	for(int a=1;a<=m;a++)
	{
		scanf("%d",&op);
			if(op==1)//区间修改(乘)
			{
				scanf("%d%d%lld",&i,&j,&k);
				update2(i,j,k);
			}
			else if(op==2)//区间修改(加)
			{
				scanf("%d%d%lld",&i,&j,&k);
				update(i,j,k);				
			}
			else//查询
			{
				scanf("%d%d",&i,&j);
				printf("%lld\n",query(i,j)%kk);
			}
	}
	return 0;
}
2023/12/3 17:35
加载中...