线段树2模版求助QwQ
查看原帖
线段树2模版求助QwQ
134593
反手一只MJJ楼主2020/11/6 21:25

RT

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define rd read()
typedef long long int ll;
using namespace std;
const ll MAXN=100002;
inline ll read(){
	ll x=0;
	char g=getchar();
	bool f=true;
	for(;!isdigit(g);g=getchar())if(g=='-')f=!f;
	for(;isdigit(g);g=getchar())x=(x<<1)+(x<<3)+(g^48);
	return f?x:-x;
}
ll n,m,p;
ll sum[MAXN<<2];
ll add[MAXN<<2];
ll mut[MAXN<<2];
ll a[MAXN];
ll tree_build(int l,int r,int rt){
	add[rt]=0;
	mut[rt]=1;
	if(l==r)return sum[rt]=a[l];
	ll mid=(l+r)>>1;
	return sum[rt]=(tree_build(l,mid,rt<<1)
				+tree_build(mid+1,r,rt<<1|1))%p;
}
void push_down(ll l,ll r,ll rt){
	ll mid=(l+r)>>1;
	if(mut[rt]!=1){
		sum[rt<<1]=sum[rt<<1]*mut[rt]%p;
		sum[rt<<1|1]=sum[rt<<1|1]*mut[rt]%p;
		mut[rt<<1]=mut[rt<<1]*mut[rt]%p;
		mut[rt<<1|1]=mut[rt<<1|1]*mut[rt]%p;
		mut[rt]=1;
	}
	if(add[rt]!=0){
		sum[rt<<1]=(sum[rt<<1]+add[rt]*(mid-l+1))%p;
		sum[rt<<1|1]=(sum[rt<<1|1]+add[rt]*(r-mid))%p;
		add[rt<<1]=(add[rt<<1]+add[rt])%p;
		add[rt<<1|1]=(add[rt<<1|1]+add[rt])%p;
		add[rt]=0;
	}
	sum[rt<<1]=(sum[rt<<1]+add[rt]*(mid-l+1))%p;
	sum[rt<<1|1]=(sum[rt<<1|1]+add[rt]*(r-mid))%p;
	add[rt<<1]=(add[rt<<1]+add[rt])%p;
	add[rt<<1|1]=(add[rt<<1|1]+add[rt])%p;
	add[rt]=0;
	return;
}
void ADD(ll L,ll R,ll l,ll r,ll rt,ll k){
	if(L<=l&&r<=R){
		add[rt]=(add[rt]+k)%p;
		sum[rt]=(sum[rt]+(r-l+1)*k)%p;
		return;
	}
	ll mid=(r+l)>>1;
	push_down(l,r,rt);
	if(L<=mid)ADD(L,R,l,mid,rt<<1,k);
	if(mid+1<=R)ADD(L,R,mid+1,r,rt<<1|1,k);
	sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%p;
	return;
}
ll SUM(ll L,ll R,ll l,ll r,ll rt){
	if(L<=l&&r<=R)return sum[rt];
	ll res=0;
	ll mid=(r+l)>>1;
	push_down(l,r,rt);
	if(L<=mid)res=(res+SUM(L,R,l,mid,rt<<1))%p;
	if(mid+1<=R)res=(res+SUM(L,R,mid+1,r,rt<<1|1))%p;
	return res;
}
void MUT(ll L,ll R,ll l,ll r,ll rt,ll k){
	if(L<=l&&r<=R){
		mut[rt]=(mut[rt]*k)%p;
		add[rt]=(add[rt]*k)%p;
		sum[rt]=(sum[rt]*k)%p;
		return;
	}
	ll mid=(r+l)>>1;
	push_down(l,r,rt);
	if(L<=mid)MUT(L,R,l,mid,rt<<1,k);
	if(mid+1<=R)MUT(L,R,mid+1,r,rt<<1|1,k);
	sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%p;
	return;
}
int main(){
	freopen("P3373_2.in","r",stdin);
	freopen("res.txt","w",stdout);
	n=rd,m=rd,p=rd;
	for(int i=1;i<=n;i++)a[i]=rd%p;
	tree_build(1,n,1);
	for(int i=1;i<=m;i++){
		ll x=rd,L=rd,R=rd;
		if(x==1){
			MUT(L,R,1,n,1,rd%p);
		}else if(x==2){
			ADD(L,R,1,n,1,rd%p);
		}else if(x==3){
			printf("%lld\n",SUM(L,R,1,n,1)%p);
		}
	}
	return 0;
}

tu

2020/11/6 21:25
加载中...