样例过了,测试点只有30分,求调!!!
查看原帖
样例过了,测试点只有30分,求调!!!
933604
LYBT楼主2023/8/11 23:38
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,q,m,a[N],f[N*4],v1[N*4],v2[N*4],op,x,y,k;
inline void push_down(int k,int l,int r){
	int mid=(l+r)>>1;
	f[k*2]=(v2[k]*f[k*2]+v1[k]*(mid-l+1))%m;
	f[k*2+1]=(v2[k]*f[k*2+1]+v1[k]*(r-mid))%m;
	v2[k*2]=(v2[k*2]*v2[k])%m;
	v2[k*2+1]=(v2[k*2+1]*v2[k])%m;
	v1[k*2]=(v1[k*2]+v1[k])%m;
	v1[k*2+1]=(v1[k*2+1]+v1[k])%m;
	v2[k]=1;
	v1[k]=0;
}
inline void buildtree(int k,int l,int r){
	v1[k]=0,v2[k]=1;
	if(l==r){
		f[k]=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	buildtree(k*2,l,mid),buildtree(k*2+1,mid+1,r);
	f[k]=(f[k*2]+f[k*2+1])%m;
}
inline void add(int k,int l,int r,int x,int y,int z){
	if(l==x&&r==y){
		v1[k]=(v1[k]+z)%m;
		f[k]=(f[k]+(r-l+1)*z)%m;
		return ;
	}
	push_down(k,l,r);
	int mid=(l+r)>>1;
	if(y<=mid) add(k*2,l,mid,x,y,z);
	else if(x>mid) add(k*2+1,mid+1,r,x,y,z);
	else add(k*2,l,mid,x,mid,z),add(k*2+1,mid+1,r,mid+1,y,z);
	f[k]=(f[k*2]+f[k*2+1])%m;
}
inline void insert(int k,int l,int r,int x,int y,int z){
	if(l==x&&r==y){
		v2[k]=(v2[k]*z)%m;
		v1[k]=(v1[k]*z)%m;
		f[k]=(f[k]*z)%m;
		return ;
	}
	push_down(k,l,r);
	int mid=(l+r)>>1;
	if(y<=mid) insert(k*2,l,mid,x,y,z);
	else if(x>mid) insert(k*2+1,mid+1,r,x,y,z);
	else insert(k*2,l,mid,x,mid,z),insert(k*2+1,mid+1,r,mid+1,y,z);
	f[k]=(f[k*2]+f[k*2+1])%m;
}
int calc(int k,int l,int r,int x,int y){
	if(l==x&&r==y) return f[k];
	push_down(k,l,r);
	int mid=(l+r)>>1;
	if(y<=mid) return calc(k*2,l,mid,x,y);
	else if(x>mid) return calc(k*2+1,mid+1,r,x,y);
	else return (calc(k*2,l,mid,x,mid)+calc(k*2+1,mid+1,r,mid+1,y))%m;
}
signed main(){
	cin>>n>>q>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	buildtree(1,1,n);
	while(q--){
		cin>>op;
		if(op==1){
			cin>>x>>y>>k;
			insert(1,1,n,x,y,k);
		}
		if(op==2){
			cin>>x>>y>>k;
			add(1,1,n,x,y,k);
		}
		if(op==3){
			cin>>x>>y;
			cout<<calc(1,1,n,x,y)<<endl;
		}
	}
	return 0;
}
2023/8/11 23:38
加载中...