社区讨论

30 pts, why?

P3373【模板】线段树 2参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@lo10lv7f
此快照首次捕获于
2023/10/22 13:15
2 年前
此快照最后确认于
2023/11/02 12:44
2 年前
查看原帖
CPP
#include <bits/stdc++.h>

using namespace std;

#define de(x) cout<<#x<<"="<<x<<endl

using ll = long long;

const int N = 1e5+5;

ll n,q,mod,a[N];

struct segtree {
	ll dat[N<<2],tm[N<<2],ta[N<<2];
	void pushup(int k){
		dat[k]=(dat[k<<1]+dat[k<<1|1])%mod;
	}
	void pushdown(int k,int l,int r){
		int mid=l+r>>1;
		dat[k<<1]=(dat[k<<1]*tm[k]%mod+ta[k]*(mid-l+1)%mod)%mod;
		dat[k<<1|1]=(dat[k<<1|1]*tm[k]%mod+ta[k]*(r-mid)%mod)%mod;
		(tm[k<<1]*=tm[k])%=mod;
		(tm[k<<1|1]*=tm[k])%=mod;
		(ta[k<<1]+=ta[k])%=mod;
		(ta[k<<1|1]+=ta[k])%=mod;
		tm[k]=1;
		ta[k]=0;
	}
	void build(int k,int l,int r){
	//	cout<<k<<","<<l<<","<<r<<endl;
		tm[k]=1;
		ta[k]=0;
		if (l==r){
			dat[k]=a[l];
			return;
		}
		int mid=l+r>>1;
		build(k<<1,l,mid);
		build(k<<1|1,mid+1,r);
		pushup(k);
	}
	void updm(int k,int l,int r,int ql,int qr,ll v){
		if (r<ql || l>qr){
			return;
		}
		if (ql<=l && r<=qr){
			(dat[k]*=v)%=mod;
			(tm[k]*=v)%=mod;
			(ta[k]*=v)%=mod;
			return;
		}
		int mid=l+r>>1;
		pushdown(k,l,r);
		updm(k<<1,l,mid,ql,qr,v);
		updm(k<<1|1,mid+1,r,ql,qr,v);
		pushup(k);
	}
	void upda(int k,int l,int r,int ql,int qr,ll v){
		if (r<ql || l>qr){
			return;
		}
		if (ql<=l && r<=qr){
			(dat[k]+=v*(r-l+1)%mod)%=mod;
			(ta[k]+=v)%=mod;
			return;
		}
		int mid=l+r>>1;
		pushdown(k,l,r);
		upda(k<<1,l,mid,ql,qr,v);
		upda(k<<1|1,mid+1,r,ql,qr,v);
		pushup(k);
	}
	ll Q(int k,int l,int r,int ql,int qr){
	//	cout<<k<<":"<<l<<","<<r<<" and "<<ql<<","<<qr<<endl;
		if (r<ql || l>qr){
			return 0;
		}
		if (ql<=l && r<=qr){
			return dat[k];
		}
		int mid=l+r>>1;
		pushdown(k,l,r);
		ll vl=Q(k<<1,l,mid,ql,qr);
		ll vr=Q(k<<1|1,mid+1,r,ql,qr);
		pushup(k);
		return (vl+vr)%mod;
	}
} t;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin>>n>>q>>mod;
	for (int i=1; i<=n; i++){
		cin>>a[i];
		a[i]%=mod;
	}
	t.build(1,1,n);
	while (q--){
		ll op,x,y,k;
		cin>>op>>x>>y;
		if (op==1){
			cin>>k;
			t.updm(1,1,n,x,y,k%mod);
		}
		else if (op==2){
			cin>>k;
			t.upda(1,1,n,x,y,k%mod);
		}
		else{
			cout<<t.Q(1,1,n,x,y)<<endl;
		}
	//cout<<t.Q(1,1,n,1,n)<<endl;
	//cout<<t.Q(1,1,n,1,1)<<endl;
	}
	return 0;
}

// don't waste time!!!

回复

4 条回复,欢迎继续交流。

正在加载回复...