30pts求条玄关
查看原帖
30pts求条玄关
1428495
KMYC楼主2025/7/31 13:57

乘法懒标记初始化为1了,向下传也先乘后加了

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5;
int n,q,mod,a[N];
struct segment_tree{ int sum,lazy_mul,lazy_add; }t[N<<2];
void build(int p,int l,int r){
	t[p].lazy_mul=1;
	if(l==r){
		t[p].sum=a[l];
		return;
	}
	int lson=p<<1,rson=p<<1|1,mid=l+(r-l)/2;
	build(lson,l,mid);
	build(rson,mid+1,r);
	t[p].sum=(t[lson].sum+t[rson].sum)%mod;
}
void push_down(int p,int l,int r){
	int lson=p<<1,rson=p<<1|1,mid=l+(r-l)/2;
	int add=t[p].lazy_add,mul=t[p].lazy_mul;
	if(mul!=0&&mul!=1){
		t[lson].lazy_mul*=mul,t[lson].lazy_mul%=mod;
		t[rson].lazy_mul*=mul,t[rson].lazy_mul%=mod;
		t[lson].lazy_add*=mul,t[lson].lazy_add%=mod;
		t[rson].lazy_add*=mul,t[rson].lazy_add%=mod;
		t[lson].sum*=mul; t[lson].sum%=mod; 
		t[rson].sum*=mul; t[rson].sum%=mod;
		t[p].lazy_mul=1;
	}
	if(add!=0){
		t[lson].lazy_add+=add,t[lson].lazy_add%=mod;
		t[rson].lazy_add+=add,t[rson].lazy_add%=mod;
		t[lson].sum+=(mid-l+1)*add%mod; t[lson].sum%=mod;
		t[rson].sum+=(r-mid)*add%mod;   t[rson].sum%=mod;
		t[p].lazy_add=0;
	}
}
void update(int p,int l,int r,int ul,int ur,int val,bool flag){
	if(ul<=l&&r<=ur){
		if(flag){
			t[p].sum+=(r-l+1)*val%mod; t[p].sum%=mod;
			t[p].lazy_add+=val; t[p].lazy_add%=mod;
		}else{
			t[p].sum*=val; t[p].sum%=mod;
			t[p].lazy_add*=val; t[p].lazy_add%=mod;
			t[p].lazy_mul*=val; t[p].lazy_mul%=mod;
		}
		return;
	}
	push_down(p,l,r);
	int lson=p<<1,rson=p<<1|1,mid=l+(r-l)/2;
	if(ul<=mid) update(lson,l,mid,ul,ur,val,flag);
	if(ur>mid) update(rson,mid+1,r,ul,ur,val,flag);
	t[p].sum=(t[lson].sum+t[rson].sum)%mod;
}
int query(int p,int l,int r,int ql,int qr){
	if(ql<=l&&r<=qr) return t[p].sum%mod;
	int lson=p<<1,rson=p<<1|1,mid=l+(r-l)/2;
	push_down(p,l,r);
	int ans=0;
	if(ql<=mid) ans+=query(lson,l,mid,ql,qr),ans%=mod;
	if(qr>mid) ans+=query(rson,mid+1,r,ql,qr),ans%=mod;
	return ans%mod;
}
signed main(){
	cin>>n>>q>>mod;
	for(int i=1;i<=n;i++) cin>>a[i],a[i]%=mod;
	build(1,1,n);
	while(q--){
		int op,x,y,k; cin>>op>>x>>y;
		if(op==1){
			cin>>k;
			update(1,1,n,x,y,k%mod,false);
		}else if(op==2){
			cin>>k;
			update(1,1,n,x,y,k%mod,true);
		}else{
			cout<<query(1,1,n,x,y)<<"\n";
		}
	}
	return 0;
} 
2025/7/31 13:57
加载中...