线段树模板2求助 QAQ
查看原帖
线段树模板2求助 QAQ
616605
hyc777楼主2023/7/14 19:15
#include<iostream>
#define ll long long
using namespace std;
struct Tree{
	ll L,R,sum,plus,time;
}tr[800005];
ll n,q,mod,i,opt,x,y,k;
void build(ll p,ll L,ll R){
	tr[p]={L,R,0,0,1};
	if(L==R) return;
	ll mid=(L+R)>>1;
	build(p<<1,L,mid);
	build((p<<1)+1,mid+1,R);
}
void pushdown(int p){
	int mid=(tr[p].L+tr[p].R)>>1;
	tr[p<<1].sum=(tr[p<<1].sum*tr[p].time+tr[p].plus*(mid-tr[p].L+1))%mod;
	tr[(p<<1)+1].sum=(tr[(p<<1)+1].sum*tr[p].time+tr[p].plus*(tr[p].R-mid))%mod;
	//sum
	tr[p<<1].time=(tr[p<<1].time*tr[p].time)%mod;
	tr[(p<<1)+1].time=(tr[(p<<1)+1].time*tr[p].time)%mod;
	//time
	tr[p<<1].plus=(tr[p<<1].plus*tr[p].time+tr[p].plus)%mod;
	tr[(p<<1)+1].plus=(tr[(p<<1)+1].plus*tr[p].time+tr[p].plus)%mod;
	//plus
	tr[p].time=1; 
	tr[p].plus=0; 
}
void modify(ll p,ll l,ll r,ll b){
	if(tr[p].L>r||tr[p].R<l) return;
	if(tr[p].L>=l&&tr[p].R<=r){
		tr[p].plus=(tr[p].plus+b)%mod;
		tr[p].sum=((tr[p].R-tr[p].L+1)*b+tr[p].sum)%mod;
		return;
	}
	pushdown(p);
	modify(p<<1,l,r,b);modify((p<<1)+1,l,r,b);
	tr[p].sum=(tr[p<<1].sum+tr[(p<<1)+1].sum)%mod;
}//加法
void modify2(ll p,ll l,ll r,ll b){
	if(tr[p].L>r||tr[p].R<l) return;
	if(tr[p].L>=l&&tr[p].R<=r){
		tr[p].sum=(tr[p].sum*b)%mod;
        tr[p].time=(tr[p].time*b)%mod;
        tr[p].plus=(tr[p].plus*b)%mod;
		return;
	}
	pushdown(p);
	modify(p<<1,l,r,b);modify((p<<1)+1,l,r,b);
	tr[p].sum=(tr[p<<1].sum+tr[(p<<1)+1].sum)%mod;
}//乘法
ll query(ll p,ll a,ll b){
	if(tr[p].L>b||tr[p].R<a) return 0;
	if(tr[p].L>=a&&tr[p].R<=b) return tr[p].sum;
	pushdown(p);
	return (query(p<<1,a,b)+query((p<<1)+1,a,b))%mod;
}
int main(){
	cin>>n>>q>>mod;
	build(1,1,n);
	for(int a=1;a<=n;a++){
		cin>>i;
		modify(1,a,a,i);
	}
	for(int a=1;a<=q;a++){
		cin>>opt;
		if(opt==1){
			cin>>x>>y>>k;
			modify2(1,x,y,k);
		}
		else if(opt==2){
			cin>>x>>y>>k;
			modify(1,x,y,k);
		}
		else{
			cin>>x>>y;
			cout<<query(1,x,y)<<endl;
		}
	}
	return 0;
}
2023/7/14 19:15
加载中...