线段树0pts求调
查看原帖
线段树0pts求调
950465
opwanneng楼主2023/11/28 19:08
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e5+100;
int n,m,x,y,z,op,ans,mod;
int a[N];
struct tree{
	int l,r;
	int he;
	int lazy,la;
}t[N*4+100];
void down(int k){
	t[k*2].he=(t[k*2].he*t[k].la+t[k].lazy*(t[k*2].r-t[k*2].l+1))%mod;
	t[k*2].la=(t[k*2].la*t[k].la)%mod;
	t[k*2].lazy=(t[k*2].lazy*t[k].la+t[k].lazy);
	t[k*2+1].he=(t[k*2+1].he*t[k].la+t[k].lazy*(t[k*2+1].r-t[k*2+1].l+1))%mod;
	t[k*2+1].la=(t[k*2+1].la*t[k].la)%mod;
	t[k*2+1].lazy=(t[k*2+1].lazy*t[k].la+t[k].lazy);
	t[k].lazy=0;t[k].la=1;
}
void build(int l,int r,int k){
	t[k].lazy=0;t[k].la=1;
	t[k].l=l;t[k].r=r;
	if(l==r){
		t[k].he=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,k*2);
	build(mid+1,r,k*2+1);
	t[k].he=(t[k*2].he+t[k*2+1].he)%mod;
}
void add1(int k){//区间修改a[x~y]*=z
	if(x<=t[k].l&&t[k].r<=y){
		t[k].lazy=(z*t[k].lazy)%mod;
		t[k].la=(z*t[k].la)%mod;
		t[k].he=(z*t[k].he)%mod;
		return;
	}
	down(k);
	int mid=(t[k].l+t[k].r)>>1;
	if(x<=mid) add1(k*2);
	if(y>mid) add1(k*2+1);
	t[k].he=(t[k*2].he+t[k*2+1].he)%mod;
}
void add2(int k){//区间修改a[x~y]+=z
	if(x<=t[k].l&&t[k].r<=y){
		t[k].lazy=(t[k].lazy+z)%mod;
		t[k].he+=(t[k].he+z*(t[k].r-t[k].l+1))%mod;
		return;
	}
	down(k);
	int mid=(t[k].l+t[k].r)>>1;
	if(x<=mid) add2(k*2);
	if(y>mid) add2(k*2+1);
	t[k].he=(t[k*2].he+t[k*2+1].he)%mod;
}
void solve(int k){//区间查询x~y
	if(x<=t[k].l&&t[k].r<=y){
		ans=(ans+t[k].he)%mod;
		return;
	}
	down(k);
	int mid=(t[k].l+t[k].r)>>1;
	if(x<=mid) solve(k*2);
	if(y>mid) solve(k*2+1);
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m>>mod;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,n,1);
	for(int i=1;i<=m;i++){
		cin>>op;
		if(op==1){
			cin>>x>>y>>z;
			add1(1);
		}else if(op==2){
			cin>>x>>y>>z;
			add2(1);
		}else{
			cin>>x>>y;
			ans=0;
			solve(1);
			cout<<ans<<"\n";
		}
	}
	return 0;
}
2023/11/28 19:08
加载中...