30pts求助(悬赏关注)
查看原帖
30pts求助(悬赏关注)
632911
Falsing楼主2022/11/24 21:45
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M=1e5+2;
int n,m,mod,top;
ll a[M],ans[M];
struct SegmentTree{
   int l,r;
   ll add,adm=1,sum;
   #define l(p) tree[p].l
   #define r(p) tree[p].r
   #define add(p) tree[p].add
   #define sum(p) tree[p].sum
   #define adm(p) tree[p].adm
}tree[M*4];
void build(int p,int l,int r){//build tree
   l(p)=l;r(p)=r;
   if(l==r){
   	sum(p)=a[l];
   	return;
   }
   int mid=(l+r)/2;
   build(p*2,l,mid);
   build(p*2+1,mid+1,r);
   sum(p)=(sum(p*2)+sum(p*2+1))%mod;
}
void spread(int p){ //lazy
   if(adm(p)>1){
   	sum(p*2)=(sum(p*2)*adm(p))%mod;
   	sum(p*2+1)=(sum(p*2+1)*adm(p))%mod;
   	adm(p*2)=(adm(p)*adm(p*2))%mod;
   	adm(p*2+1)=(adm(p)*adm(p*2+1))%mod;
   	add(p*2)=(add(p*2)*adm(p))%mod;
   	add(p*2+1)=(add(p*2+1)*adm(p))%mod;
   	adm(p)=1;
   }
   if(add(p)){
   	sum(p*2)=(sum(p*2)+(ll)add(p)*(r(p*2)-l(p*2)+1))%mod;
   	sum(p*2+1)=(sum(p*2+1)+(ll)add(p)*(r(p*2+1)-l(p*2+1)+1))%mod;
   	add(p*2)=(add(p)+add(p*2))%mod;
   	add(p*2+1)=(add(p*2+1)+add(p))%mod;
   	add(p)=0;
   }
}
ll ask(int p,int l,int r){ //ask value
   if(l(p)>=l &&r(p)<=r) return sum(p);
   spread(p);
   int mid=(l(p)+r(p))/2;
   ll val=0;
   if(l<=mid)val+=ask(p*2,l,r);
   if(r>mid) val+=ask(p*2+1,l,r);
   return val%mod;
}
void chanadd(int p,int l,int r,int d){ //change add
   if(l(p)>=l && r(p)<=r){
   	sum(p)=(sum(p)+(ll)d*(r(p)-l(p)+1))%mod;
   	add(p)=(add(p)+d)%mod;
   	return;
   }
   spread(p);
   int mid=(l(p)+r(p))/2;
   if(l<=mid) chanadd(p*2,l,r,d);
   if(r>mid) chanadd(p*2+1,l,r,d);
   sum(p)=(sum(p*2)+sum(p*2+1))%mod;
}
void chanmul(int p,int l,int r,int d){//change multi
   if(l(p)>=l && r(p)<=r){
   	sum(p)=(sum(p)*d)%mod;
   	adm(p)=(adm(p)*d)%mod;
   	add(p)=(add(p)*d)%mod;
   	return;
   }
   spread(p);
   int mid=(l(p)+r(p))/2;
   if(l<=mid) chanmul(p*2,l,r,d);
   if(r>mid) chanmul(p*2+1,l,r,d);
   sum(p)=(sum(p*2)+sum(p*2+1))%mod;
}
int main(){
   ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
   cin>>n>>m>>mod;
   for(int i=1;i<=n;i++) {
   	cin>>a[i];
   	a[i]%=mod;
   }
   build(1,1,n);
   int t,l,r,d;
   while(m--){
   	cin>>t>>l>>r;
   	if(t==3){
   		ans[++top]=ask(1,l,r);
   		//cout<<ask(1,l,r)<<endl;
   	}
   	else{
   		cin>>d;
   		if(t==1) chanmul(1,l,r,d);
   		else chanadd(1,l,r,d);
   	}
   }
   for(int i=1;i<=top;i++) cout<<ans[i]<<endl;
   return 0;
}
2022/11/24 21:45
加载中...