分块30求调 悬关
查看原帖
分块30求调 悬关
726098
hytallenxu楼主2023/12/20 18:51

rt

#include <iostream>
#include <cmath>
using namespace std;
#define reg register
#define int unsigned long long
const int maxn=1e5+10;
int n,q,m,size;
int arr[maxn],l[maxn],r[maxn],belong[maxn],tagmul[maxn],tagsum[maxn], sum[maxn];
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

void write(int x)
{
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

void reset(int block){
	for(int i=l[block];i<=r[block];i++) arr[i]*=tagmul[block],arr[i]%=m,arr[i]+=tagsum[block],arr[i]%=m;
	tagmul[block]=1,tagsum[block]=0;
}

void work(){
	size=sqrt(n);
	int num=n/size;
	int begin=1,which=1;
	for(reg int i=1;i<=n;i++){
		if(i<=1000) tagmul[i]=1;
		if(begin>size) begin=1,which++;
		belong[i]=which;
		if(begin==1) l[which]=i;
		if(begin==size or i==n) r[which]=i;
		sum[which]+=arr[i];
		begin++;
	}
}

void add(int x, int y, int k){
	int block1=belong[x],block2=belong[y];
	if(block1==block2){
		sum[block1]+=((y-x+1)*k);
		for(int i=x;i<=y;i++){
			arr[i]+=k;
			arr[i]%=m;
		}
		sum[block1]%=m;
	}else{
		if(x!=l[block1]){
			sum[block1]+=((r[block1]-x+1)*k);
			for(reg int i=x;i<=r[block1];i++){
				arr[i]+=k;
				arr[i]%=m;
			}
			sum[block1]%=m;
			block1++;
		}
		if(y!=r[block2]){
			sum[block2]+=((l[block2]-y+1)*k);
			for(reg int i=l[block2];i<=y;i++){
				arr[i]+=k;
				arr[i]%=m;
			}
			sum[block2]%=m;
			block2--;
		}
		for(reg int i=block1;i<=block2;i++){
			tagsum[i]+=k;
			sum[i]+=((r[i]-l[i]+1)*k);
			sum[i]%=m;
		}
		
	}
}

void mul(int x, int y, int k){
	int block1=belong[x],block2=belong[y];
	
	if(block1==block2){
		reset(block1);
		for(reg int i=x;i<=y;i++){
			int tmp=arr[i];
			arr[i]*=k;
			arr[i]%=m;
			sum[block1]+=(arr[i]-tmp);
			sum[block1]%=m;
		}
	}else{
		if(x!=l[block1]){
			reset(block1);
			for(reg int i=x;i<=r[block1];i++){
				int tmp=arr[i];
				arr[i]*=k;
				arr[i]%=m;
				sum[block1]+=(arr[i]-tmp);
				sum[block1]%=m;
			}
			block1++;
		}
		if(y!=r[block2]){
			reset(block2);
			for(reg int i=l[block2];i<=y;i++){
				int tmp=arr[i];
				arr[i]*=k;
				arr[i]%=m;
				sum[block2]+=(arr[i]-tmp);
				sum[block2]%=m;
			}
			block2--;
		}
		for(reg int i=block1;i<=block2;i++){
			tagmul[i]*=k;
			sum[i]*=k;
			sum[i]%=m;
			tagsum[i]*=k;
		}
	}
	
}

int query(int x, int y){
	int block1=belong[x],block2=belong[y],cnt=0;
		if(x!=l[block1]){
			for(int i=x;i<=r[block1];i++){
				cnt+=(arr[i]*tagmul[block1]+tagsum[block1]);
				cnt%=m;
				//write(cnt);//cout<<" "<<arr[i]<<" "<<tagmul[block1]<<" "<<tagsum[block1]<<endl; 
			}
			block1++;
		}
		if(y!=r[block2]){
			for(reg int i=l[block2];i<=y;i++){
				cnt+=(arr[i]*tagmul[block2]+tagsum[block2]);
				cnt%=m;
				//write(cnt);//cout<<"*"<<tagmul[block2]<<" "<<tagsum[block2]<<endl;
			}
			block2--;
		}
		for(reg int i=block1;i<=block2;i++){
			cnt+=sum[i];
			cnt%=m;
			//write(cnt);cout<<"*"<<endl; 
		}
	return cnt;
}

signed main(){
	n=read(),q=read(),m=read();
	for(reg int i=1;i<=n;i++) arr[i]=read();
	work();
	while(q--){
		int a,b,c,d;
		a=read(),b=read(),c=read();
		if(a==1){
			d=read();
			mul(b,c,d);
		}else if(a==2){
			d=read();
			add(b,c,d);
		}else{
			write((query(b,c))%m);putchar('\n');
		}
	}
	return 0;
}

写的有点臭,望大佬们不要喷

2023/12/20 18:51
加载中...