求大佬指点(自认为码风优良)
查看原帖
求大佬指点(自认为码风优良)
238883
jfor679542638楼主2020/5/1 09:49
(自认为码风优良)~~~~
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100086;
#define ll long long
#define l(x) tree[x].l
#define r(x) tree[x].r
#define sum(x) tree[x].sum
#define add(x) tree[x].add
#define mul(x) tree[x].mul
int a[MAXN], n, m, mod;
void cheng(int p, int l, int r, int k);
void jia(int p, int l, int r, int k);
struct SegmentTree
{
    int l, r;
    int sum, add; //乘法标记和加法标记
    int mul;
} tree[4 * MAXN];
void build(int p, int l, int r)
{
    l(p) = l;
    r(p) = r;
    if (l == r)
    {
        sum(p) = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(p * 2, l, mid);
    build(p * 2 + 1, mid + 1, r);
    sum(p) = sum(p * 2) + sum(p * 2 + 1);
}
void spread(int p, int t)
{
    if (t == 1 && add(p))
    {
        sum(p * 2) += add(p) * (r(p * 2) - l(p * 2) + 1);
        sum(p * 2 + 1) += add(p) * (r(p * 2 + 1) - l(p * 2 + 1) + 1);
        add(p * 2) += add(p);
        add(p * 2 + 1) += add(p);
        add(p) = 0;
    }
    if (t == 2 && mul(p))
    {
        sum(p * 2) *= mul(p);
        sum(p * 2) %= mod;
        sum(p * 2 + 1) *= mul(p);
        sum(p * 2 + 1) %= mod;
        mul(p * 2) *= mul(p);
        mul(p * 2) %= mod;
        mul(p * 2 + 1) *= mul(p);
        mul(p * 2 + 1) %= mod;
        mul(p) = 1;
    }
}
void jia(int p, int l, int r, int d)
{
    if (l <= l(p) && r >= r(p))
    {
        sum(p) += d * (r(p) - l(p) + 1);
        add(p) += d;
        return;
    }
    spread(p, 1);
    int mid = (l(p) + r(p)) >> 1;
    if (l <= mid)
        jia(p * 2, l, r, d);
    if (r > mid)
        jia(p * 2 + 1, l, r, d);
    sum(p) = sum(p * 2) + sum(p * 2 + 1);
}
void cheng(int p, int l, int r, int k)
{
    if (l <= l(p) && r >= r(p))
    {
        sum(p) *= k;
        sum(p) %= mod;
        mul(p) *= k;
        mul(p) %= mod;
        return;
    }
    spread(p, 2);
    int mid = (l(p) + r(p)) >> 1;
    if (l <= mid)
        cheng(p * 2, l, r, k);
    if (r > mid)
        cheng(p * 2 + 1, l, r, k);
    sum(p) = sum(p * 2) + sum(p * 2 + 1);
}
int ask(int p, int l, int r)
{
    if (l <= l(p) && r >= r(p))
        return sum(p);
    spread(p, 1);
    spread(p, 2);
    int mid = (l(p) + r(p)) >> 1;
    int val = 0;
    if (l <= mid)
    {
        val %= mod;
        val += ask(p * 2, l, r);
    }

    if (r > mid)
    {
        val %= mod;
        val += ask(2 * p + 1, l, r);
    }
    return val % mod;
}
int main()
{
    cin >> n >> m >> mod;
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++)
        mul(i) = 1;
    build(1, 1, n);
    for (int i = 1; i <= m; i++)
    {
        int opt, x, y, k;
        scanf("%d%d%d", &opt, &x, &y);
        if (opt == 1)
        {
            scanf("%d", &k);
            cheng(1, x, y, k);
        }
        else if (opt == 2)
        {
            scanf("%d", &k);
            jia(1, x, y, k);
        }
        else
            printf("%d\n", ask(1, x, y));
    }
    return 0;
}

2020/5/1 09:49
加载中...