求调线段树
查看原帖
求调线段树
399936
辰云楼主2021/10/30 18:31
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

struct jjy{
	int l,r;
	int add,mul,d;
}t[400005];

int a[100005];
int n,m,p;

inline void build(int o,int l,int r){
	t[o].add=0,t[o].mul=1;
	t[o].l=l,t[o].r=r;
	if(l==r){t[o].d=a[l];return;}
	int mid=(l+r)/2;
	build(o<<1,l,mid);
	build(o<<1|1,mid+1,r);
	t[o].d=(t[o<<1].d+t[o<<1|1].d)%p;
}

inline void maintain(int o){
	t[o].d=(t[o<<1].d+t[o<<1|1].d)%p;
}

inline void pushdown(int o){
	t[o<<1].d=(t[o<<1].d*t[o].mul+t[o].add*(t[o<<1].r-t[o<<1].l+1))%p;
	t[o<<1|1].d=(t[o<<1|1].d*t[o].mul+t[o].add*(t[o<<1|1].r-t[o<<1|1].l+1))%p;
	t[o<<1].mul=(t[o<<1].mul*t[o].mul)%p;
	t[o<<1|1].mul=(t[o<<1|1].mul*t[o].mul)%p;
	t[o<<1].add=(t[o<<1].add*t[o].mul+t[o].add)%p;
	t[o<<1|1].add=(t[o<<1|1].add*t[o].mul+t[o].add)%p;
	t[o].add=0,t[o].mul=1;
	return;
}

inline void mul(int o,int l,int r,int k){
	if(l<=t[o].l&&t[o].r<=r){
		t[o].d=(t[o].d*k)%p;
		t[o].add=(t[o].add*k)%p;
		t[o].mul=(t[o].mul*k)%p;
		return;
	}
	pushdown(o);
	int mid=(t[o].l+t[o].r)/2;
	if(l<=mid)mul(o<<1,l,mid,k); //else maintain(o<<1);
	if(r>mid)mul(o<<1|1,mid+1,r,k); //else maintain(o<<1|1);
	maintain(o);
}

inline void add(int o,int l,int r,int k){
	if(l<=t[o].l&&t[o].r<=r){
		t[o].add=(t[o].add+k)%p;
		t[o].d=(t[o].d+k*(t[o].r-t[o].l+1))%p;
		return;
	}
	pushdown(o);
	int mid=(t[o].l+t[o].r)/2;
	if(l<=mid)add(o<<1,l,mid,k); //else maintain(o<<1);
	if(r>mid)add(o<<1|1,mid+1,r,k); //else maintain(o<<1|1);
	maintain(o);
}

inline int query(int o,int l,int r){
	if(l<=t[o].l&&t[o].r<=r)return t[o].d%p;
	pushdown(o);
	int mid=(t[o].r+t[o].l)/2;
	int ans=0;
	if(l<=mid)ans=(ans+query(o<<1,l,r))%p;
	if(r>mid)ans=(ans+query(o<<1|1,l,r))%p;
	return ans%p;
}

int main(){
	n=read(),m=read(),p=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	build(1,1,n);
	while(m--){
		int op,x,y,k;
		op=read();x=read();y=read();
		if(op==1){
			k=read();
			mul(1,x,y,k);
		}else if(op==2){
			k=read();
			add(1,x,y,k);
		}else{
			printf("%d\n",query(1,x,y)%p);
		}
	}
}
2021/10/30 18:31
加载中...