线段树2求条,玄两关
查看原帖
线段树2求条,玄两关
773915
endswitch楼主2024/1/28 09:28
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,q,x,y,k,op,mod,a[N];
struct SGT {
	int ans[N<<2],tag1[N<<2],tag2[N<<2];
	inline int ls(int p) {return p<<1;}
	inline int rs(int p) {return p<<1|1;}
	inline void psup(int p) {ans[p]=ans[ls(p)]+ans[rs(p)],ans[p]%=mod;}
	inline void build(int p=1,int L=1,int R=n) {
		tag2[p]=1;
		if(L==R) {
			ans[p]=a[L];
			return;
		}
		int mid=(L+R)>>1;
		build(ls(p),L,mid),build(rs(p),mid+1,R),psup(p);
	}
	inline void work1(int p,int L,int R,int k) {tag1[p]+=k,ans[p]+=(R-L+1)*k,tag1[p]%=mod,ans[p]%=mod;}
	inline void work2(int p,int L,int R,int k) {tag1[p]*=k,tag2[p]*=k,ans[p]*=k,tag1[p]%=mod,tag2[p]%=mod,ans[p]%=mod;}
	inline void psd(int p,int L,int R) {
		int mid=(L+R)>>1;
		if(tag2[p]!=1) work2(ls(p),L,mid,tag2[p]),work2(rs(p),mid+1,R,tag2[p]),tag2[p]=1;
		if(tag1[p]) work1(ls(p),L,mid,tag1[p]),work1(rs(p),mid+1,R,tag1[p]),tag1[p]=0;
	}
	inline void add1(int l,int r,int k,int p=1,int L=1,int R=n) {
		if(l<=L&&R<=r) {
			work1(p,L,R,k);
			return;
		}
		psd(p,L,R);
		int mid=(L+R)>>1;
		if(l<=mid) add1(l,r,k,ls(p),L,mid);
		if(r>mid) add1(l,r,k,rs(p),mid+1,R);
		psup(p);
	}
	inline void add2(int l,int r,int k,int p=1,int L=1,int R=n) {
		if(l<=L&&R<=r) {
			work2(p,L,R,k);
			return;
		}
		psd(p,L,R);
		int mid=(L+R)>>1;
		if(l<=mid) add2(l,r,k,ls(p),L,mid);
		if(r>mid) add2(l,r,k,rs(p),mid+1,R);
		psup(p);
	}
	inline int gts(int l,int r,int p=1,int L=1,int R=n) {
		int res=0;
		if(l<=L&&R<=r) return ans[p];
		psd(p,L,R);
		int mid=(L+R)>>1;
		if(l<=mid) res+=gts(l,r,ls(p),L,mid);
		if(r>mid) res+=gts(l,r,rs(p),mid+1,R);
		return res;
	}
} t;
signed main() {
	ios_base::sync_with_stdio(NULL);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin>>n>>q>>mod;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	t.build();
	while(q--) {
		cin>>op>>x>>y;
		if(op==1) cin>>k,t.add1(x,y,k);
		else if(op==2) cin>>k,t.add2(x,y,k);
		else cout<<t.gts(x,y)<<'\n';
	}
	return 0;
}
2024/1/28 09:28
加载中...