分块求调
查看原帖
分块求调
767660
zhaohanwen楼主2023/10/19 10:54

经过调试,乘法的部分写炸了,但是不知道为什么。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
const int N=5e5+5;
ll block[N],id[N],a[N],tag1[N],tag2[N];
int len;
int n,m;

inline int qpow(int a,int b)
{
	int ans=1;
	for(;b;b>>=1,a=a*a%m) if(b&1) ans=ans*a%m;
	return ans;
}

void build()
{
	//清空全部块
	memset(block,0,sizeof block);
	memset(tag2,1,sizeof tag2);
	fill(tag2,tag2+N,1);
	len=1;
	for(int i=1; i<=n; i++)
	{
		id[i]=(i-1)/len+1;
		block[id[i]]+=a[i];
		block[id[i]]%=m;
	}
}
void update1(int l,int r,ll w)
{
	int p1=id[l],p2=id[r];
	if(p1==p2)
	{
		for(int i=l; i<=r; i++)
		{
			a[i]*=w;
			a[i]%=m;
			block[p1]*=w;
			block[p1]%=m;
		}
		return;
	}
	for(int i=l; i<=p1*len; i++)
	{
		a[i]*=w;
		a[i]%=m;
		block[p1]*=w;
		block[p1]%=m;
	}
	for(int i=(p2-1)*len+1; i<=min(r,n); i++)
	{
		a[i]*=w;
		a[i]%=m;
		block[p2]*=w;
		block[p2]%=m;
	}
	for(int i=p1+1; i<=p2-1; i++)
	{
		block[i]*=1LL*len*w;
		block[i]%=m;
		tag2[i]*=w;
		tag2[i]%=m;
	} 
	return;
}
void update2(int l,int r,ll w)
{
	int p1=id[l],p2=id[r];
	if(p1==p2)
	{
		for(int i=l; i<=r; i++)
		{
			a[i]+=w;
			a[i]%=m;
			block[p1]+=w;
			block[p1]%=m;
		}
		return;
	}
	for(int i=l; i<=p1*len; i++)
	{
		a[i]+=w;
		a[i]%=m;
		block[p1]+=w;
		block[p1]%=m;
	}
	for(int i=(p2-1)*len+1; i<=min(r,n); i++)
	{
		a[i]+=w;
		a[i]%=m;
		block[p2]+=w;
		block[p2]%=m;
	}
	for(int i=p1+1; i<=p2-1; i++)
	{
		block[i]+=1LL*len*w;
		block[i]%=m;
		tag1[i]+=w;
		tag1[i]%=m;
	}
	return;
}
void pushdown(int k)
{
	if(tag1[k])
	{
		for(int i=(k-1)*len+1; i<=k*len; i++)
		{
			a[i]+=tag1[k];
			a[i]%=m;
		}
		tag1[k]=0;
	}
	if(tag2[k]!=1)
	{
		for(int i=(k-1)*len+1;i<=k*len;i++)
		{
			a[i]*=tag2[k];
			a[i]%=m;
		}
		tag2[k]=1;
	}
	return;
}
ll query(int l,int r)
{
	int p1=id[l],p2=id[r];
	ll ans=0;
	pushdown(p1);
	pushdown(p2);
	if(p1==p2)
	{
		for(int i=l; i<=r; i++)
		{
			ans+=a[i];
			ans%=m;
		}
		return ans;
	}
	for(int i=l; i<=p1*len; i++) ans+=a[i],ans%=m;
	for(int i=(p2-1)*len+1; i<=min(r,n); i++)
	{
		ans+=a[i];
		ans%=m;
	}
	for(int i=p1+1; i<=p2-1; i++) ans+=block[i],ans%=m;
	return ans;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int q;
	cin>>n>>q>>m;
	for(int i=1; i<=n; i++) cin>>a[i];
	build();
	while(q--)
	{
		int op;
		int l,r;
		cin>>op>>l>>r;
		if(op==1)
		{
			int k;
			cin>>k;
			update1(l,r,k);
		}
		else if(op==2)
		{
			int k;
			cin>>k;
			update2(l,r,k);
		}
		else
		{
			cout<<query(l,r)%m<<endl;
		}
	}
	return 0;
}

验证码 666f 祭。

2023/10/19 10:54
加载中...