30分线段树求调
查看原帖
30分线段树求调
1127572
AlephZero0楼主2024/11/24 12:19
#include<bits/stdc++.h>
#define int long long
#define l(a) tree[a].l
#define r(a) tree[a].r
#define s(a) tree[a].sum
#define laza(a) tree[a].laza
#define lazm(a) tree[a].lazm
using namespace std;
const int Maxn=400010;
int n,q,m,a[Maxn];
struct Node
{
    int l,r,sum,laza,lazm;
}tree[Maxn];
void update(int k)
{
    s(k)=(s(k<<1)+s(k<<1|1))%m;
}
void z(int k)
{
	s(k<<1)*=lazm(k)%m;
	s(k<<1)+=laza(k)*(r(k<<1)-l(k<<1)+1);
	s(k<<1)%=m;
	s(k<<1|1)*=lazm(k)%m;
	s(k<<1|1)+=laza(k)*(r(k<<1|1)-l(k<<1|1)+1);
	s(k<<1|1)%=m;
    lazm(k<<1)*=lazm(k)%m;
    laza(k<<1)*=lazm(k)%m;
    laza(k<<1)+=laza(k);
    laza(k<<1)%=m;
    lazm(k<<1|1)*=lazm(k)%m;
    laza(k<<1|1)*=lazm(k)%m;
    laza(k<<1|1)+=laza(k);
    laza(k<<1|1)%=m;
    laza(k)=0;
    lazm(k)=1;
}
void build(int q,int e,int k)
{
    l(k)=q;
    r(k)=e;
    laza(k)=0;
    lazm(k)=1;
    if(q==e){
        s(k)=a[q]%m;
        return;
    }
    int mid=q+e>>1;
    build(q,mid,k<<1);
    build(mid+1,e,k<<1|1);
	update(k);
}
void add(int x,int y,int k,int c)
{
    if(x<=l(k)&&r(k)<=y){
        s(k)+=c*(r(k)-l(k)+1);
        s(k)%=m;
        laza(k)+=c;
        laza(k)%=m;
        return;
    }
    z(k);
    int mid=l(k)+r(k)>>1;
    if(x<=mid){
        add(x,y,k<<1,c);
    }
    if(mid+1<=y){
        add(x,y,k<<1|1,c);
    }
    update(k);
}
void mul(int x,int y,int k,int c)
{
    if(x<=l(k)&&r(k)<=y){
        s(k)*=c%m;
        lazm(k)*=c%m;
        laza(k)*=c%m;
        return;
    }
    z(k);
    int mid=l(k)+r(k)>>1;
    if(x<=mid){
        mul(x,y,k<<1,c);
    }
    if(mid+1<=y){
        mul(x,y,k<<1|1,c);
    }
    update(k);
}
int op(int x,int y,int k)
{
    if(x<=l(k)&&r(k)<=y){
        return s(k);
    }
    z(k);
    int mid=l(k)+r(k)>>1,s=0;
    if(x<=mid){
        s+=op(x,y,k<<1);
        s%=m;
    }
    if(mid+1<=y){
        s+=op(x,y,k<<1|1);
        s%=m;
    }
    return s;
}
signed main()
{
    scanf("%lld%lld%lld",&n,&q,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",a+i);
    }
    build(1,n,1);
    int t,x,y,c;
    for(int i=1;i<=q;i++){
        scanf("%lld%lld%lld",&t,&x,&y);
        if(t!=3){
            scanf("%lld",&c);
            if(t==1){
            	mul(x,y,1,c);
			}
			else{
            	add(x,y,1,c);
			}
        }
        else{
            printf("%lld\n",op(x,y,1));
        }
    }
}
2024/11/24 12:19
加载中...