0分分块求调
查看原帖
0分分块求调
973237
dingyyds11111楼主2024/11/20 16:56
#include <bits/stdc++.h>
#define int long long
using namespace std;
void cmax(int &x, int y) {x = (x > y) ? x : y;}
void cmin(int &x, int y) {x = (x < y) ? x : y;}
int mod = 10007;
int n, block, m;
int v[1000005], bl[1000005], add[3400], ch[3400], sum[3400];
inline void build() {
    block = sqrt(n);
    for (int i = 1; i <= n; i ++)  bl[i] = (i - 1) / block + 1, sum[bl[i]] += v[i];
    for (int i = 1; i <= bl[n]; i ++) ch[i] = 1;
}
void change(int x) {
    for (int i = (x - 1) * block + 1; i <= min(n, block * x); i ++) {
        v[i] = (v[i] * ch[x] + add[x]) % mod;
    }
    add[x] = 0, ch[x] = 1;
}
void solve(int op, int a, int b, int c) {
    change(bl[a]);
    for (int i = a; i <= min(b, block * bl[a]); i ++) {
        if (op == 0) v[i] += c, sum[bl[a]] += c;
        else {sum[bl[a]] -= v[i]; v[i] *= c;sum[bl[a]] += v[i];}
        v[i] %= mod;
    }
    if (bl[a] != bl[b]) {
        change(bl[b]);
        for (int i = (bl[b] - 1) * block + 1; i <= b; i ++) {
            if (op == 0) v[i] += c, sum[bl[b]] += c;
            else {sum[bl[b]] -= v[i]; v[i] *= c;sum[bl[b]] += v[i];}
            v[i] %= mod;
        }
    }
    for (int i = bl[a] + 1; i < bl[b]; i ++) {
        if (op == 0) add[i] = (add[i] + c) % mod;
        else {
            add[i] = (add[i] * c) % mod;
            ch[i] = (ch[i] * c) % mod;
        }
    }
}
int query(int a, int b) {
    int ans = 0;
    for (int i = a; i <= min(bl[a] * block, b); i ++) 
        ans += v[i] * ch[bl[i]] + add[bl[a]];
    if (bl[a] != bl[b]) {
        for (int j = (bl[b] - 1) * block + 1; j <= b; j ++) 
            ans += v[j] * ch[bl[j]] + add[bl[b]];
    }
    for (int i = bl[a] + 1; i < bl[b]; i ++)
        ans += sum[i] * ch[i] + block * add[i];
    return ans;
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m >> mod;
    for (int i = 1; i <= n; i ++) {
        cin >> v[i];
    }
    build();
    for (int i = 1; i <= m; i ++) {
        int op, l, r, c;
        cin >> op >> l >> r;
        if (op == 3) op = 2;
        else if (op == 2) op = 0;
        if (op == 2) {
            cout << query(l, r) % mod << '\n';
        }
        else {
            cin >> c;
            solve(op, l, r, c);
        }
    }
    return 0;
}
2024/11/20 16:56
加载中...