刚学OI两年半的MnZn求调线段树版子
查看原帖
刚学OI两年半的MnZn求调线段树版子
388415
Sudohry楼主2022/11/22 19:26

RT,样例过,数据全红

//
//  main.cpp
//  SegT_2
//
//  Created by Mac on 2022/11/22.
//

#include <iostream>
#include <cstdio>
#define N 100005
#define ll long long

using namespace std;

ll n, m, p, op, x, y, k, a[N<<2], ans[N<<2], add[N<<2], mul[N<<2];

inline ll ls (ll x) { return x << 1 ; }
inline ll rs (ll x) { return x << 1 | 1 ; }

void flash (ll x, ll l, ll r, ll mu, ll ad) {
    ans[x] = ans[x] * mu + ad * (r - l + 1);
    mul[x] *= mu;
    add[x] = add[x] * mu + ad;
    ans[x] %= p; mul[x] %= p; add[x] %= p;
    return;
}

void pushup (ll x) {
    ans[x] = ans[ls(x)] + ans[rs(x)];
    ans[x] %= p;
    return;
}

void pushdown (ll x, ll l, ll r) {
    ll mid = (l + r) >> 1;
    flash(ls(x), l, mid, mul[x], add[x]);
    flash(rs(x), mid+1, r, mul[x], add[x]);
    add[x] = 0; mul[x] = 1;
    return;
}

void build (ll l, ll r, ll pos) {
    mul[pos] = 1;
    if (l == r) {
        ans[pos] = a[l];
        return;
    }
    
    ll mid = (l + r) >> 1;
    build(l, mid, ls(pos));
    build(mid+1, r, rs(pos));
    
    pushup(pos);
    return;
}

void update_add (ll x, ll l, ll r, ll ul, ll ur, ll k) {
    if (l >= ul && r <= ur) {
        flash(x, l, r, 1, k);
        return;
    }
    
    ll mid = (l + r) >> 1;
    if (ul <= mid) update_add(ls(x), l, mid, ul, ur, k);
    if (ur > mid) update_add(rs(x), mid+1, r, ul, ur, k);
    
    pushup(x);
    return;
}

void update_mul (ll x, ll l, ll r, ll ul, ll ur, ll k) {
    if (l >= ul && r <= ur) {
        flash(x, l, r, k, 0);
        return;
    }
    
    ll mid = (l + r) >> 1;
    if (ul <= mid) update_mul(ls(x), l, mid, ul, ur, k);
    if (ur > mid) update_mul(rs(x), mid+1, r, ul, ur, k);
    
    pushup(x);
    return;
}

ll query (ll x, ll l, ll r, ll ql, ll qr) {
    if (l >= ql && r <= qr) {
        return ans[x];
    }
    
    pushdown(x, l, r);
    ll mid = (l + r) >> 1, res = 0;
    if (ql <= mid) res += query(ls(x), l, mid, ql, qr);
    if (qr > mid) res += query(rs(x), mid+1, r, ql, qr);
    
    return res % p;
}

int main(int argc, const char * argv[]) {
//    insert code here...
//    std::cout << "Hello, World!\n";
    scanf("%lld%lld%lld", &n, &m, &p);
    for (int i=1; i<=n; ++i) {
        scanf("%lld", &a[i]);
        a[i] %= p;
    }
    build (1, n, 1);
    while (m--) {
        scanf("%lld", &op);
        switch (op) {
            case 1:
                scanf("%lld%lld%lld", &x, &y, &k);
                update_mul(1, 1, n, x, y, k);
                break;
            
            case 2:
                scanf("%lld%lld%lld", &x, &y, &k);
                update_add(1, 1, n, x, y, k);
                break;
            
            case 3:
                scanf("%lld%lld", &x, &y);
                printf("%lld\n", query(1, 1, n, x, y));
                break;
            
            default:
                break;
        }
    }
    return 0;
}

2022/11/22 19:26
加载中...