30分 求调
查看原帖
30分 求调
597060
GGapa楼主2023/7/22 14:16
#include <iostream>
#include <cstdio>

#define maxn 100005
using namespace std;
#define int unsigned long long

int a[maxn];
int n, m, mod;

struct stru_tree
{
    int left, right;
    long long sum, lazy, mu;
};
stru_tree tree[maxn * 4];

inline void make_tree(int it, int left, int right)
{
    tree[it].left = left;
    tree[it].right = right;
    tree[it].mu = 1;
    if (left == right)
    {
        tree[it].sum = a[left];
        return;
    }
    int middle = (left + right) >> 1;
    make_tree(it * 2, left, middle);
    make_tree(it * 2 + 1, middle + 1, right);
    tree[it].sum = (tree[it * 2].sum + tree[it * 2 + 1].sum) % mod;
}

inline void update(int it)
{
    if (tree[it].lazy != 0)
    {
        tree[it * 2].sum = (tree[it * 2].sum*tree[it].mu + ((tree[it * 2].right - tree[it * 2].left + 1) * tree[it].lazy) % mod) % mod;
        tree[it * 2 + 1].sum = (tree[it * 2 + 1].sum*tree[it].mu + ((tree[it * 2 + 1].right - tree[it * 2 + 1].left + 1) * tree[it].lazy) % mod) % mod;
        tree[it * 2].mu = (tree[it * 2].mu * tree[it].mu) % mod;
        tree[it * 2 + 1].mu = (tree[it * 2 + 1].mu * tree[it].mu) % mod;
        tree[it * 2].lazy = (tree[it * 2].lazy * tree[it].mu + tree[it].lazy) % mod;
        tree[it * 2 + 1].lazy = (tree[it * 2 + 1].lazy * tree[it].mu + tree[it].lazy) % mod;

        tree[it].mu = 1;
        tree[it].lazy = 0;
    }
}

inline void Add(int it, int left, int right, long long add)
{
    if (left <= tree[it].left && right >= tree[it].right)
    {
        tree[it].lazy = (tree[it].lazy + add) % mod;
        tree[it].sum = (tree[it].sum + ((tree[it].right - tree[it].left + 1) * add) % mod) % mod;
        return;
    }
    update(it);
    int middle = (tree[it].left + tree[it].right) >> 1;
    if (left <= middle)
        Add(it * 2, left, right, add);
    if (right > middle)
        Add(it * 2 + 1, left, right, add);
    tree[it].sum = (tree[it * 2].sum + tree[it * 2 + 1].sum) % mod;
}

inline void mu(int it, int left, int right, long long add)
{
    if (left <= tree[it].left && right >= tree[it].right)
    {
        tree[it].mu = (tree[it].mu * add) % mod;
        tree[it].lazy = (tree[it].lazy * add) % mod;
        tree[it].sum = (tree[it].sum * add) % mod;
        return;
    }
    update(it);
    int middle = (tree[it].left + tree[it].right) >> 1;
    if (left <= middle)
        mu(it * 2, left, right, add);
    if (right > middle)
        mu(it * 2 + 1, left, right, add);
    tree[it].sum = (tree[it * 2].sum + tree[it * 2 + 1].sum) % mod;
}

inline long long reply(int it, int left, int right)
{
    if (left <= tree[it].left && right >= tree[it].right)
    {
        return tree[it].sum;
    }
    update(it);
    int middle = (tree[it].left + tree[it].right) >> 1;
    long long ans = 0;
    if (left <= middle)
        ans = (ans + reply(it * 2, left, right)) % mod;
    if (right > middle)
        ans = (ans + reply(it * 2 + 1, left, right)) % mod;
    return ans;
}

signed main()
{
    scanf("%lld%lld%lld", &n, &m, &mod);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &a[i]);
    make_tree(1, 1, n);
    while (m--)
    {
        int op;
        scanf("%lld", &op);
        if (op == 1)
        {
            int x, y, k;
            scanf("%lld%lld%lld", &x, &y, &k);
            mu(1, x, y, k);
        }
        else if (op == 2)
        {
            int x, y, k;
            scanf("%lld%lld%lld", &x, &y, &k);
            Add(1, x, y, k);
        }
        else
        {
            int x, y;
            scanf("%lld%lld", &x, &y);
            printf("%u\n", reply(1, x, y));
        }
    }
    return 0;
}

2023/7/22 14:16
加载中...