大神求助!!!帮帮我这个蒟蒻的线段树吧
查看原帖
大神求助!!!帮帮我这个蒟蒻的线段树吧
490978
小超手123楼主2022/8/6 15:02
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
int n,m,mod,opt;
long long a[maxn],w[maxn*4];
long long add[maxn*4],mu[maxn*4]; //加法和乘法的lazy标记 
void pushop(int u){ //计算当前节点的和 
	w[u]=w[u*2]+w[u*2+1]; 
}
void build(int u,int L,int R){ //建树 
	if(L==R){
		w[u]=a[L];
		return;
	}
	int mid=(L+R)/2;
	build(u*2,L,mid);
	build(u*2+1,mid+1,R);
	pushop(u);
}
void maketag(int u,int L,int R,int x,int y){ //+x,*y
    w[u]*=y;
	w[u]+=(R-L+1)*x;
	w[u]%=mod;
	add[u]+=x;
	if(y!=0){
		add[u]*=y;
		mu[u]*=y;
	}
	add[u]%=mod;
	mu[u]%=mod;
}
void pushdown(int u,int L,int R){
	int mid=(L+R)/2;
	maketag(u*2,L,mid,add[u],mu[u]);
	maketag(u*2+1,mid+1,R,add[u],mu[u]);
	add[u]=0;
	mu[u]=1;
}
bool OutofRange(int L,int R,int l,int r){ //完全没有交集 
	return L>r||R<l;
}
bool InRange(int L,int R,int l,int r){ //完全包含 
	return L>=l&&R<=r;
}
int query(int u,int L,int R,int l,int r){
	if(OutofRange(L,R,l,r))return 0;
	if(InRange(L,R,l,r))return w[u];
	pushdown(u,L,R);
	int mid=(L+R)/2;
	return query(u*2,L,mid,l,r)%mod+query(u*2+1,mid+1,R,l,r)%mod;
}
void update_add(int u,int L,int R,int l,int r,int x){
	if(OutofRange(L,R,l,r))return;
	if(InRange(L,R,l,r)){
		maketag(u,L,R,x,0);
		return;
	}
	pushdown(u,L,R);
	int mid=(L+R)/2;
	update_add(u*2,L,mid,l,r,x);
	update_add(u*2+1,mid+1,R,l,r,x);
	pushop(u);
}
void update_mu(int u,int L,int R,int l,int r,int x){
	if(OutofRange(L,R,l,r))return;
	if(InRange(L,R,l,r)){
		maketag(u,L,R,0,x);
		return;
	}
	pushdown(u,L,R);
	int mid=(L+R)/2;
	update_mu(u*2,L,mid,l,r,x);
	update_mu(u*2+1,mid+1,R,l,r,x);
	pushop(u);
}
int main(){
	cin>>n>>m>>mod;
	for(int i=1;i<=n;i++)
	    cin>>a[i];
	build(1,1,n);
	while(m--){
		int x,y,k;
		cin>>opt;
		if(opt==1){
			cin>>x>>y>>k;
			update_mu(1,1,n,x,y,k);
		}
		if(opt==2){
			cin>>x>>y>>k;
			update_add(1,1,n,x,y,k);
		}
		if(opt==3){
			cin>>x>>y;
			cout<<query(1,1,n,x,y)<<endl;
		}
	}
	return 0;
}		
2022/8/6 15:02
加载中...