线段树 30pts求助
查看原帖
线段树 30pts求助
554584
thlm楼主2023/9/7 17:17
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define mn 100010
#define ll long long
using namespace std;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while('0'>ch || ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while('0'<=ch && ch<='9'){x=x*10+(ch-'0');ch=getchar();}
	return x*f;
};
int n,q;
ll m;
ll st[mn];
struct name{
	int l,r;
	ll ans;
	ll cf,jf;
}a[mn*4];
void build(int x,int y,int b){
	a[b].l=x;a[b].r=y;
	if(x==y) {a[b].ans=st[x]%m;return;}
	int mid=(x+y)>>1;
	build(x,mid,b<<1);build(mid+1,y,b<<1|1);
	a[b].ans=(a[b<<1].ans+a[b<<1|1].ans)%m;
};
void spread(int b){
	if(a[b].cf){
		a[b<<1].jf=(a[b<<1].jf*a[b].cf)%m;
		a[b<<1|1].jf=(a[b<<1|1].jf*a[b].cf)%m;
		a[b<<1].cf=max((a[b<<1].cf*a[b].cf),a[b].cf)%m;
		a[b<<1|1].cf=max((a[b<<1|1].cf*a[b].cf),a[b].cf)%m;
		a[b<<1].ans=(a[b<<1].ans*a[b].cf)%m;
		a[b<<1|1].ans=(a[b<<1|1].ans*a[b].cf)%m;
		a[b].cf=0;
	}
	if(a[b].jf){
		a[b<<1].ans=(a[b<<1].ans+a[b].jf*(a[b<<1].r-a[b<<1].l+1))%m;
		a[b<<1].jf=(a[b<<1].jf+a[b].jf)%m;
		a[b<<1|1].ans=(a[b<<1|1].ans+a[b].jf*(a[b<<1|1].r-a[b<<1|1].l+1))%m;
		a[b<<1|1].jf=(a[b<<1|1].jf+a[b].jf)%m;
		a[b].jf=0;
	}
};
void addj(int x,int y,int b,ll z){
	if(a[b].l>=x && a[b].r<=y){
		a[b].ans=(a[b].ans+z*(a[b].r-a[b].l+1))%m;
		a[b].jf=(a[b].jf+z)%m;
		return;
	}
	spread(b);
	int mid=(a[b].l+a[b].r)>>1;
	if(x<=mid) addj(x,y,b<<1,z);
	if(mid+1<=y) addj(x,y,b<<1|1,z);
	a[b].ans=(a[b<<1].ans+a[b<<1|1].ans)%m;
};
void addc(int x,int y,int b,ll z){
	if(a[b].l>=x && a[b].r<=y){
		a[b].ans=(a[b].ans*z)%m;a[b].cf=max((a[b].cf*z),z)%m;
		a[b].jf=(a[b].jf*z)%m;
		return;
	}
	spread(b);
	int mid=(a[b].l+a[b].r)>>1;
	if(x<=mid) addc(x,y,b<<1,z);
	if(mid+1<=y) addc(x,y,b<<1|1,z);
	a[b].ans=(a[b<<1].ans+a[b<<1|1].ans)%m;
};
ll find(int x,int y,int b){
	if(a[b].l>=x && a[b].r<=y) return a[b].ans;
	spread(b);
	int mid=(a[b].l+a[b].r)>>1;
	ll ansl=0;
	if(x<=mid) ansl=ansl+find(x,y,b<<1);
	if(mid+1<=y) ansl=ansl+find(x,y,b<<1|1);
	return ansl%m;
};
int main(){
	freopen("1.in","r",stdin);
	freopen("1.out","w",stdout);
	n=read();q=read();m=read();
	for(int i=1;i<=n;i++) st[i]=read();
	build(1,n,1);
	for(int i=1;i<=q;i++){
		int opt=read();
		int x=read(),y=read();
		ll k;
		if(opt==1){
			k=read();
			addc(x,y,1,k);
		}
		if(opt==2){
			k=read();
			addj(x,y,1,k);
		}
		if(opt==3){
			printf("%lld\n",find(x,y,1));
		}
	}
	return 0;
}
2023/9/7 17:17
加载中...