初学线段树,求调
查看原帖
初学线段树,求调
597716
IT__windy楼主2022/3/10 22:32
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct tree{
	int l,r;
	ll v,add,mu;
	#define l(x) e[x].l
	#define r(x) e[x].r
	#define v(x) e[x].v
	#define add(x) e[x].add
	#define mu(x) e[x].mu
}e[100005*4];
ll a[100005];
int n,m,mod;
int ls(int x){return x<<1;}
int rs(int x){return x<<1|1;}
void down(int x){
	int mid=(l(x)+r(x))/2;
	v(ls(x))=(v(ls(x))*mu(x)+add(x)*(mid-l(x)+1))%mod;
	v(rs(x))=(v(rs(x))*mu(x)+add(x)*(r(x)-mid))%mod;
	mu(ls(x))=(mu(ls(x))*mu(x))%mod;
	mu(rs(x))=(mu(rs(x))*mu(x))%mod;
	add(ls(x))=(add(ls(x))*mu(x)+add(x))%mod;
	add(rs(x))=(add(rs(x))*mu(x)+add(x))%mod;
	mu(x)=1;
	add(x)=0;
	return;
}
void update_add(int x,int l,int r,ll num){
	if(l<=l(x)&&r>=r(x)){
		v(x)=(v(x)+num*(r-l+1))%mod;
		add(x)=(add(x)+num)%mod;
		return;
	}
	down(x);
	int mid=(l(x)+r(x))/2;
	if(l<=mid)update_add(ls(x),l,r,num);
	if(r>mid)update_add(rs(x),l,r,num);
	v(x)=(v(ls(x))+v(rs(x)))%mod;
}

void update_mu(int x,int l,int r,ll num){
	if(l<=l(x)&&r>=r(x)){
		v(x)=(v(x)*num)%mod;
		mu(x)=(mu(x)*num)%mod;
		add(x)=(add(x)*num)%mod;
		return;
	}
	down(x);
	int mid=(l(x)+r(x))/2;
	if(l<=mid)update_mu(ls(x),l,r,num);
	if(r>mid)update_mu(rs(x),l,r,num);
	v(x)=(v(ls(x))+v(rs(x)))%mod;
}

ll query(int x,int l,int r){
	if(l<=l(x)&&r>=r(x))return v(x);
	down(x);
	int mid=(l(x)+r(x))/2;
	ll ans=0;
	if(l<=mid)ans+=query(ls(x),l,r);
	if(r>mid)ans+=query(rs(x),l,r);
	return ans%mod;
}

void build(int x,int l,int r){
	l(x)=l,r(x)=r;
	mu(x)=1,add(x)=0;
	if(l==r){v(x)=a[l];return;}
	int mid=(l+r)/2;
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	v(x)=(v(ls(x))+v(rs(x)))%mod;
}

int main(){
	scanf("%d%d%d",&n,&m,&mod);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	build(1,1,n);
	while(m--){
        int chk;
        scanf("%d", &chk);
        int x, y;
        long long k;
        if(chk==1){
            scanf("%d%d%lld", &x, &y, &k);
            update_mu(1,x,y,k);
        }
        else if(chk==2){
            scanf("%d%d%lld", &x, &y, &k);
            update_add(1,x,y,k);
        }
        else{
            scanf("%d%d", &x, &y);
            printf("%lld\n", query(1, x, y));
        }		
	}
}
2022/3/10 22:32
加载中...