WA 0pts求调
查看原帖
WA 0pts求调
414912
Althemeta楼主2022/11/5 12:23
#include <cstdio>

typedef long long LL;

const int N = 1e5 + 10;

struct SGT
{
    LL x, add, mul;
};

int n, m, a[N]; LL p;
SGT tr[N << 2];

inline void build (int rt = 1, int l = 1, int r = n)
{
    tr[rt].add = 0, tr[rt].mul = 1;
    if (l == r) tr[rt].x = a[l];
    else
    {
        int mid = l + r >> 1;
        build (rt << 1, l, mid), build (rt << 1 | 1, mid + 1, r);
        tr[rt].x = tr[rt << 1].x + tr[rt << 1 | 1].x;
    }
    tr[rt].x %= p;
}

inline void push_up (int rt)
{
    tr[rt].x = (tr[rt << 1].x + tr[rt << 1 | 1].x) % p;
}

inline void push_down (int rt, int mid, int l, int r)
{
    tr[rt << 1].x = (tr[rt << 1].x * tr[rt].mul + tr[rt].add * (mid - l + 1)) % p;
    tr[rt << 1 | 1].x = (tr[rt << 1 | 1].x * tr[rt].mul + tr[rt].add * (r - mid)) % p;
    tr[rt << 1].mul = tr[rt << 1].mul * tr[rt].mul % p;
    tr[rt << 1 | 1].mul = tr[rt << 1 | 1].mul * tr[rt].mul % p;
    tr[rt << 1].add = (tr[rt << 1].add * tr[rt].mul + tr[rt].add) % p;
    tr[rt << 1 | 1].add = (tr[rt << 1 | 1].add * tr[rt].mul + tr[rt].add) % p;
    tr[rt].add = 0, tr[rt].mul = 1;
}

inline void update_add (int l, int r, LL k, int rt = 1, int nl = 1, int nr = n)
{
    if (l > nr || r < nl) return ;
    if (l <= nl && r >= nr) tr[rt].x = (tr[rt].x + k * (nr - nl + 1)) % p, tr[rt].add = (tr[rt].add + k) % p;
    else
    {
        int mid = nl + nr >> 1;
        push_down (rt, mid, nl, nr);
        update_add (l, r, k, rt << 1, nl, mid), update_add (l, r, k, rt << 1 | 1, mid + 1, nr);
        push_up (rt);
    }
}

inline void update_mul (int l, int r, LL k, int rt = 1, int nl = 1, int nr = n)
{
    if (l > nr || r < nl) return ;
    if (l <= nl && r >= nr) tr[rt].x = tr[rt].x * k % p,  tr[rt].add = tr[rt].add * k % p, tr[rt].mul = tr[rt].mul * k % p;
    else
    {
        int mid = nl + nr >> 1;
        push_down (rt, mid, nl, nr);
        update_add (l, r, k, rt << 1, nl, mid), update_add (l, r, k, rt << 1 | 1, mid + 1, nr);
        push_up (rt);
    }
}

inline LL query (int l, int r, int rt = 1, int nl = 1, int nr = n)
{
    if (l > nr || r < nl) return 0;
    if (l <= nl && r >= nr) return tr[rt].x;
    else
    {
        int mid = nl + nr >> 1;
        push_down (rt, mid, nl, nr);
        return (query (l, r, rt << 1, nl, mid) + query (l, r, rt << 1 | 1, mid + 1, nr)) % p;
    }
}

int main ()
{
    scanf ("%d %d %lld", &n, &m, &p);
    for (int i = 1; i <= n; ++i) scanf ("%d", &a[i]);

    build ();
    while (m--)
    {
        int opt, x, y; LL k;
        scanf ("%d %d %d", &opt, &x, &y);
        if (opt == 1) scanf ("%lld", &k), update_mul (x, y, k);
        if (opt == 2) scanf ("%lld", &k), update_add (x, y, k);
        if (opt == 3) printf ("%lld\n", query (x, y));
    }
    return 0;
}
2022/11/5 12:23
加载中...