线段树全寄求调
查看原帖
线段树全寄求调
781159
Lovely_Elaina楼主2023/2/25 22:42
#include <iostream>
#define int long long
using namespace std;
const int N = 100005;

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

int t[N*4];

int pa[N*4];
int pm[N*4];

// 建树
inline void build(int k,int l,int r){
    if(l == r){
        t[k] = a[l] % p;
        return ;
    }
    
    int mid = l + r >> 1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    
    t[k] = t[k<<1] + t[k<<1|1] % p;
}

inline void apushdown(int k,int l,int r,int mid){
    if(!pa[k]) return;

    t[k*2] = (t[k*2]+(mid-l+1)*pa[k])%p;
    pa[k*2] = (pa[k*2]+pa[k])%p;

    t[k*2+1] = (t[k*2+1]+(r-mid)*pa[k])%p;
    pa[k*2+1] = (pa[k*2+1]+pa[k])%p;

    pa[k] = 0;
}

inline void mpushdown(int k,int l,int r,int mid){
    if(!pm[k]) return;

    t[k*2] = (t[k*2]*(mid-l+1)*pm[k])%p;
    pm[k*2] = (pm[k*2]*pm[k])%p;

    t[k*2+1] = (t[k*2+1]*(r-mid)*pm[k])%p;
    pm[k*2+1] = (pm[k*2+1]*pm[k])%p;

    pm[k] = 0;
}

// 询问
inline int query(int k,int l,int r,int x,int y){
    if(l <= x && y <= r){
        return t[k];
    }
    
    int res = 0;
    int mid = l + r >> 1;
    apushdown(k,l,r,mid);
    mpushdown(k,l,r,mid);
    if(x <= mid) res = res + query(k<<1,x,mid,x,y) % p;
    if(mid < y) res = res + query(k<<1|1,mid+1,y,x,y) % p;
    
    return res % p;
}

// 加法
inline void add(int k,int l,int r,int x,int y,int v){
    if(x <= l && y >= r){
        t[k] = (t[k]+(r-l+1)*v)%p;
        pa[k] = (pa[k]+v)%p;
        return ;
    }

    int mid = l + r >> 1;
    apushdown(k,l,r,mid);
    if(x <= mid) add(k*2,l,mid,x,y,v);
    if(y > mid) add(k*2+1,mid+1,r,x,y,v);

    t[k] = (t[k*2] + t[k*2+1]) % p;
}

// 乘法
inline void mul(int k,int l,int r,int x,int y,int v){
    if(x <= l && y >= r){
        t[k] = (t[k]*(r-l+1)*v)%p;
        pm[k] = (pm[k]*v)%p;
        return ;
    }

    int mid = l + r >> 1;
    mpushdown(k,l,r,mid);
    if(x <= mid) mul(k*2,l,mid,x,y,v);
    if(y > mid) mul(k*2+1,mid+1,r,x,y,v);

    t[k] = t[k*2] + t[k*2+1] % p;
}

signed main() {
    
    cin >> n >> m >> p;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    
    build(1,1,n);
    
    int z,x,y,k;
    while(m--){
        cin >> z >> x >> y;
        // 询问直接输出
        // 乘除还要读入一个数
        if(z == 3){
            cout << query(1,1,n,x,y) << endl;
        }else{
            cin >> k;
            if(z == 1){
                add(1,1,n,x,y,k);
            }else{
                mul(1,1,n,x,y,k);
            }
        }
    }
    
    return 0;
}

写崩了,没经验,真的调不下去,谢谢

2023/2/25 22:42
加载中...