60分求助!
查看原帖
60分求助!
477118
Noby_Gld楼主2022/1/20 13:09

rt,这段代码在 P3373线段树模版2 上面 A 了,在这里过不去。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,q,a[1000010],sum[5000010],p,x,y,k,num[5000010],num2[5000010];
void pushdown(ll bh,ll ln,ll rn){
	sum[bh*2]=(sum[bh*2]*num2[bh]+num[bh]*ln)%q;
	sum[bh*2+1]=(sum[bh*2+1]*num2[bh]+num[bh]*rn)%q;
	num2[bh*2]=(num2[bh*2]*num2[bh])%q;
	num2[bh*2+1]=(num2[bh*2+1]*num2[bh])%q;
	num[bh*2]=(num[bh*2]*num2[bh]+num[bh])%q;
	num[bh*2+1]=(num[bh*2+1]*num2[bh]+num[bh])%q;	
	num[bh]=0;
	num2[bh]=1;
}
void build(ll l,ll r,ll bh){
	if(l==r){
		sum[bh]=a[l];
		return;
	}
	ll mid=(l+r)>>1;
	build(l,mid,bh*2);
	build(mid+1,r,bh*2+1);
	sum[bh]=(sum[bh*2]+sum[bh*2+1])%q;
	num2[bh]=1;
}
void add(ll L,ll R,ll l,ll r,ll k,ll bh){
	if(l<=L&&r>=R){
		sum[bh]=(sum[bh]+(R-L+1)*k)%q;
		num[bh]+=k;
		return;
	}
	ll mid=(L+R)>>1;
	pushdown(bh,mid-L+1,R-mid);
	if(l<=mid) add(L,mid,l,r,k,bh*2);
	if(r>mid) add(mid+1,R,l,r,k,bh*2+1);
	sum[bh]=(sum[bh*2]+sum[bh*2+1])%q;
}
void add2(ll L,ll R,ll l,ll r,ll k,ll bh){
	if(l<=L&&r>=R){
		sum[bh]=(sum[bh]*k)%q;
		num2[bh]*=k;
		num[bh]*=k;
		return;
	}
	ll mid=(L+R)>>1;
	pushdown(bh,mid-L+1,R-mid);
	if(l<=mid) add2(L,mid,l,r,k,bh*2);
	if(r>mid) add2(mid+1,R,l,r,k,bh*2+1);
	sum[bh]=(sum[bh*2]+sum[bh*2+1])%q;
}
ll find(ll L,ll R,ll l,ll r,ll bh){
	if(l<=L&&r>=R){
		return sum[bh];
	}
	ll mid=(L+R)>>1;
	pushdown(bh,mid-L+1,R-mid);
	ll ans=0;
	if(l<=mid) ans+=find(L,mid,l,r,bh*2);
	ans%=q;
	if(r>mid) ans+=find(mid+1,R,l,r,bh*2+1);
	return ans%q;
}
int main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,n,1);
	cin>>m;
	for(int i=1;i<=m;i++){
		cin>>p>>x>>y;
		if(p==1){
			cin>>k;
			add2(1,n,x,y,k,1);
		}
		else if(p==2){
			cin>>k;
			add(1,n,x,y,k,1);
		}
		else cout<<find(1,n,x,y,1)%q<<endl;
	}
    return 0;
}
2022/1/20 13:09
加载中...