线段树求调
查看原帖
线段树求调
548203
KK_lang楼主2023/3/21 21:02
#include<bits/stdc++.h>
using namespace std;
#define int long long

const int NR = 1e5;
int n, m, p, a[NR + 10];
int seg[4 * NR + 10];
int tag1[4 * NR + 10]; // +
int tag2[4 * NR + 10]; // *

int lc(int x) { return 2 * x; }
int rc(int x) { return 2 * x + 1; }

void pushup(int x)
{ seg[x] = (seg[lc(x)] + seg[rc(x)]) % p; }

void build(int x, int l, int r)
{
    if (l == r)
    {
        seg[x] = a[l] % p;
        return;
    }
    int mid = (l + r) / 2;
    build(lc(x), l, mid);
    build(rc(x), mid + 1, r);
    pushup(x);
}

void moveTag(int x, int l, int r, int k1, int k2)
{
    seg[x] = (seg[x] * k2 + k1 * (r - l + 1)) % p;
    tag1[x] += k1, tag2[x] += k2;
}

void pushdown(int x, int l, int r)
{
    int mid = (l + r) / 2;
    moveTag(lc(x), l, mid, tag1[x], tag2[x]);
    moveTag(rc(x), mid + 1, r, tag1[x], tag2[x]);
    tag1[x] = tag2[x] = 0;
}

void update(int x, int l, int r, int ql, int qr, int k1, int k2)
{
    if (ql <= l && r <= qr)
    {
        seg[x] = (seg[x] * k2 + k1 * (r - l + 1)) % p;
        tag1[x] += k1, tag2[x] += k2;
        return;
    }
    pushdown(x, l, r);
    int mid = (l + r) / 2;
    if (ql <= mid) update(lc(x), l, mid, ql, qr, k1, k2);
    if (mid + 1 <= qr) update(rc(x), mid + 1, r, ql, qr, k1, k2);
    pushup(x);
}

int query(int x, int l, int r, int ql, int qr)
{
    if (ql <= l && r <= qr) return seg[x];
    pushdown(x, l, r);
    int ans = 0, mid = (l + r) / 2;
    if (ql <= mid) ans = (ans + query(lc(x), l, mid, ql, qr)) % p;
    if (mid + 1 <= qr) ans = (ans + query(rc(x), mid + 1, r, ql, qr)) % p;
    return ans;
}

signed main()
{
    cin >> n >> m >> p;
    for (int i = 1; i <= n; i++) cin >> a[i];
    build(1, 1, n);
    for (int i = 1; i <= m; i++)
    {
        int op, l, r, k;
        cin >> op >> l >> r;
        if (op == 1)
        {
            cin >> k;
            update(1, 1, n, l, r, 0, k);
        }
        if (op == 2)
        {
            cin >> k;
            update(1, 1, n, l, r, k, 1);
        }
        if (op == 3) cout << query(1, 1, n, l, r) << endl;
    }
    return 0;
}
2023/3/21 21:02
加载中...