分块求调,玄关
查看原帖
分块求调,玄关
629377
iamajcer楼主2025/1/31 10:31

找半天了还是没找到错哪了,求大佬帮忙看看。(先不管 TLE 的问题,现在是 WA 掉了)

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=100005, M=350;

int n, m, a[N], op, x, y, k, Mod;
int pos[N], st[M], ed[M], add[M], mul[M], sum[M];
void init()
{
	int block=sqrt(n), t=n/block;
	if (n%block!=0) t++;
	
	for (int i=1; i<=t; i++) st[i]=(i-1)*block+1, ed[i]=i*block;
	ed[t]=n;
	
	for (int i=1; i<=n; i++) pos[i]=(i-1)/block+1;
	
	for (int i=1; i<=t; i++)
	{
		add[i]=0, mul[i]=1;
		for (int j=st[i]; j<=ed[i]; j++) sum[i]=(sum[i]+a[j])%Mod;
	} 
}
void clear(int p)
{
	for (int i=st[p]; i<=ed[p]; i++) a[i]=(a[i]*mul[p]%Mod+add[p])%Mod; 
	sum[p]=(sum[p]*mul[p]%Mod+add[p]*(ed[p]-st[p]+1)%Mod)%Mod, mul[p]=1, add[p]=0;
}
void Add(int x, int y, int k)
{
	int p=pos[x], q=pos[y];
	if (p==q)
	{
		clear(p);
		for (int i=x; i<=y; i++) sum[p]=(sum[p]+k)%Mod, a[i]=(a[i]+k)%Mod;
	}
	else
	{
		clear(p);
		for (int i=x; i<=ed[p]; i++) sum[p]=(sum[p]+k)%Mod, a[i]=(a[i]+k)%Mod;
		
		for (int i=p+1; i<=q-1; i++) add[i]=(add[i]+k)%Mod;
		
		clear(q);
		for (int i=st[q]; i<=y; i++) sum[q]=(sum[q]+k)%Mod, a[i]=(a[i]+k)%Mod;
	}
}
void Mul(int x, int y, int k)
{
	int p=pos[x], q=pos[y];
	if (p==q)
	{
		clear(p);
		for (int i=x; i<=y; i++) sum[p]=(sum[p]+a[i]*(k-1)%Mod)%Mod, a[i]=(a[i]*k)%Mod;
	}
	else
	{
		clear(p);
		for (int i=x; i<=ed[p]; i++) sum[p]=(sum[p]+a[i]*(k-1)%Mod)%Mod, a[i]=(a[i]*k)%Mod;
		
		for (int i=p+1; i<=q-1; i++) mul[i]=(mul[i]*k)%Mod, add[i]=(add[i]*k)%Mod;
		
		clear(q);
		for (int i=st[q]; i<=y; i++) sum[q]=(sum[q]+a[i]*(k-1)%Mod)%Mod, a[i]=(a[i]*k)%Mod;
	}
}
int query(int x, int y)
{
	int p=pos[x], q=pos[y], res=0;
	if (p==q)
	{
		for (int i=x; i<=y; i++) res=(res+a[i]*mul[p]%Mod+add[p])%Mod;
	}
	else
	{
		for (int i=x; i<=ed[p]; i++) res=(res+a[i]*mul[p]%Mod+add[p])%Mod;
		for (int i=p+1; i<=q-1; i++) res=(res+sum[i]*mul[i]%Mod+add[i])%Mod;
		for (int i=st[q]; i<=y; i++) res=(res+a[i]*mul[q]%Mod+add[q])%Mod;
	}
	return res;
}
signed main()
{
	scanf("%d%d%lld", &n, &m, &Mod);
	for (int i=1; i<=n; i++) scanf("%lld", &a[i]);
	
	init();
	
	while (m--)
	{
		scanf("%d", &op);
		if (op==1)
		{
			scanf("%d%d%lld", &x, &y, &k);
			Mul(x, y, k);
		}
		else if (op==2)
		{
			scanf("%d%d%lld", &x, &y, &k);
			Add(x, y, k);
		}
		else
		{
			scanf("%d%d", &x, &y);
			printf("%lld\n", query(x, y));
		} 
	}
	return 0;
}
/*
5 5 31
1 2 4 9 8
1 1 3 2
2 3 4 3
1 2 5 3
2 1 3 2
3 1 5

*/
2025/1/31 10:31
加载中...