30pt求调,悬关
查看原帖
30pt求调,悬关
566243
zzx12345678楼主2024/5/26 21:46

我知道这份代码很丑,但请麻烦帮忙调一下,非常感谢。调了很久,加了各种mod,所有变量都开的ll,标记也是先乘后加,但不知道问题出在哪……

#include <bits/stdc++.h> 
#define N 500005
#define ll long long
#define ls p*2
#define rs p*2+1
using namespace std;

ll a[N],b[N];

ll n,m,u,v,w,cnt,num,tot,k,t,mod,q;
ll ans,anss;

struct node{
	ll l,r,sum,lak,lab;
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define sum(x) tree[x].sum
	#define lak(x) tree[x].lak//lak表示乘标记 
	#define lab(x) tree[x].lab//lab表示加标记 
	
}tree[N<<2];
void build(ll p,ll l,ll r){
	l(p)=l;r(p)=r;lak(p)=1;
	if(l==r){
		sum(p)=a[l];
		return;
	}
	ll mid=(l+r)>>1;
	build(ls,l,mid);//ls表示左儿子,rs表示右儿子 
	build(rs,mid+1,r);
	sum(p)=sum(ls)+sum(rs);
	sum(p)%=mod;
}
void sp(ll p){//下传标记 
	//if(lab(p)==0&&lak(p)==1)return;
	//cout<<lak(p)<<" "<<lab(p)<<endl;
	if(lak(p)==0)lak(p)=mod;
	lab(ls)=(lab(ls)+lab(p))%mod;
	lab(rs)=(lab(rs)+lab(p))%mod;
	lak(ls)=lak(ls)*lak(p)%mod;lak(rs)=lak(rs)*lak(p)%mod;
	if(lak(ls)==0)lak(ls)=mod;
	if(lak(rs)==0)lak(rs)=mod;
	ll mid=(l(p)+r(p))>>1;
	sum(ls)=sum(ls)*lak(p)%mod;
	sum(rs)=sum(rs)*lak(p)%mod;
	sum(ls)=sum(ls)+(lab(p)*(mid-l(p)+1)%mod);
	sum(rs)=sum(rs)+(lab(p)*(r(p)-mid)%mod);
	sum(ls)%=mod;sum(rs)%=mod;
	lab(p)=0;lak(p)=1;
}
void add(ll p,ll l,ll r,ll d){
	if(l<=l(p)&&r(p)<=r){
		sum(p)+=d*(r(p)-l(p)+1);
		sum(p)%=mod;
		lab(p)+=d;
		lab(p)%=mod;
		return;
	}
	sp(p);
	ll mid=(l(p)+r(p))>>1;
	if(l<=mid)add(ls,l,r,d);
	if(r>mid)add(rs,l,r,d);
	sum(p)=sum(ls)+sum(rs);
	sum(p)%=mod;
}
void ch(ll p,ll l,ll r,ll d){//乘法 
	if(l<=l(p)&&r(p)<=r){
		sum(p)=sum(p)*d%mod;
		lab(p)=lab(p)*d%mod;
		lak(p)=lak(p)*d%mod;
		if(lak(p)==0)lak(p)=mod;
		return;
	}
	sp(p);
	ll mid=(l(p)+r(p))>>1;
	if(l<=mid)ch(ls,l,r,d);
	if(r>mid)ch(rs,l,r,d);
	sum(p)=sum(ls)+sum(rs);
	sum(p)%=mod; 
}
ll ask(ll p,ll l,ll r){
	if(l<=l(p)&&r(p)<=r){
		return sum(p);
	}
	sp(p);
	ll mid=(l(p)+r(p))>>1,an=0;
	if(l<=mid)an=(an+ask(ls,l,r))%mod;
	if(r>mid)an=(an+ask(rs,l,r))%mod;
	return an%mod;
}
signed main(){
	cin>>n>>q>>mod;
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]%=mod;
	build(1,1,n);
	while(q--){
		scanf("%lld",&w);
		//cout<<endl<<w<<endl<<endl;
		if(w==1){
			scanf("%lld%lld%lld",&u,&v,&k);
			ch(1,u,v,k%mod+mod);
		}
		if(w==2){
			scanf("%lld%lld%lld",&u,&v,&k);
			add(1,u,v,k%mod);
		}
		if(w==3){
			scanf("%lld%lld",&u,&v);
			cout<<ask(1,u,v)%mod<<'\n';
		}
	}
   return 0;
}
2024/5/26 21:46
加载中...