RE70分求助
查看原帖
RE70分求助
114628
xiao_yu楼主2020/11/6 22:51

如题,2、9、10点RE 开了四倍数组,也写了防止死递归的代码(自认为不会死递归) 到现在还没搞明白为什么RE 求助各位神犇QwQ

ps:我的懒标记跟题解不大一样(我是自己琢磨的懒标记) 我的处理是当进行乘操作时就下放加懒标记,进行加操作时就下放乘懒标记

#include <iostream>
#include <cstdio>
#define LL long long
using namespace std;

struct Tree {
    int lc;
    int rc;
    LL lzr;
    LL lza;
    LL sum;

    Tree(
        int lc = 0,
        int rc = 0,
        LL lzr = 1,
        LL lza = 0,
        LL sum = 0
    ) :
    lc(lc),
    rc(rc),
    lzr(lzr),
    lza(lza),
    sum(sum)
    {}
};

int n, m;
LL MOD;
Tree tree[100000 * 4 + 10];
int ca1, ca2, ca3;
LL ca4;

void build(int id, int l, int r)//建树
{
    tree[id].lc = l;
    tree[id].rc = r;
    if (l == r) {
        scanf("%lld", &tree[id].sum);
        tree[id].sum %= MOD;
        return ;
    }

    int mid = (l + r) >> 1;
    build(id * 2, l, mid);
    build(id * 2 + 1, mid + 1, r);

    tree[id].sum = (tree[id * 2].sum + tree[id * 2 + 1].sum) % MOD;
}

void push_down_a(int id);
void push_down_r(int id);

void push_down_a(int id)//下放加懒标记
{
    if (tree[id].lc != tree[id].rc && tree[id * 2].lzr != 1) push_down_r(id * 2);
    if (tree[id].lc != tree[id].rc && tree[id * 2 + 1].lzr != 1) push_down_r(id * 2 + 1);

    tree[id * 2].lza = (tree[id * 2].lza + tree[id].lza) % MOD;
    tree[id * 2 + 1].lza = (tree[id * 2 + 1].lza + tree[id].lza) % MOD;
    tree[id * 2].sum = (tree[id * 2].sum + tree[id].lza * (tree[id * 2].rc - tree[id * 2].lc + 1)) % MOD;
    tree[id * 2 + 1].sum = (tree[id * 2 + 1].sum + tree[id].lza * (tree[id * 2 + 1].rc - tree[id * 2 + 1].lc + 1)) % MOD;
    tree[id].lza = 0;
}

void push_down_r(int id)//下放乘懒标记
{
    if (tree[id].lc != tree[id].rc && tree[id * 2].lza) push_down_a(id * 2);
    if (tree[id].lc != tree[id].rc && tree[id * 2 + 1].lza) push_down_a(id * 2 + 1);

    tree[id * 2].lzr = (tree[id * 2].lzr * tree[id].lzr) % MOD;
    tree[id * 2 + 1].lzr = (tree[id * 2 + 1].lzr * tree[id].lzr) % MOD;
    tree[id * 2].sum = (tree[id * 2].sum * tree[id].lzr) % MOD;
    tree[id * 2 + 1].sum = (tree[id * 2 + 1].sum * tree[id].lzr) % MOD;
    tree[id].lzr = 1;
}

void add(int id, int l, int r, LL k)//加法
{
    if (l <= tree[id].lc && tree[id].rc <= r) {
        if (tree[id].lc != tree[id].rc && tree[id].lzr != 1) push_down_r(id);

        tree[id].lza = (tree[id].lza + k) % MOD;
        tree[id].sum = (tree[id].sum + k * (tree[id].rc - tree[id].lc + 1)) % MOD;
        return ;
    }

    if (tree[id].lza) push_down_a(id);
    if (tree[id].lzr != 1) push_down_r(id);

    if (l <= tree[id * 2].rc) add(id * 2, l, r, k);
    if (r >= tree[id * 2 + 1].lc) add(id * 2 + 1, l, r, k);

    tree[id].sum = (tree[id * 2].sum + tree[id * 2 + 1].sum) % MOD;
}

void ride(int id, int l, int r, LL k)//乘法
{
    if (l <= tree[id].lc && tree[id].rc <= r) {
        if (tree[id].lc != tree[id].rc && tree[id].lza) push_down_a(id);

        tree[id].lzr = (tree[id].lzr * k) % MOD;
        tree[id].sum = (tree[id].sum * k) % MOD;
        return ;
    }

    if (tree[id].lza) push_down_a(id);
    if (tree[id].lzr != 1) push_down_r(id);

    if (l <= tree[id * 2].rc) ride(id * 2, l, r, k);
    if (r >= tree[id * 2 + 1].lc) ride(id * 2 + 1, l, r, k);

    tree[id].sum = (tree[id * 2].sum + tree[id * 2 + 1].sum) % MOD;
}

LL ask(int id, int l, int r)//求和
{
    if (l <= tree[id].lc && tree[id].rc <= r) {
        return tree[id].sum;
    }

    if (tree[id].lza) push_down_a(id);
    if (tree[id].lzr != 1) push_down_r(id);

    LL ans = 0;
    if (l <= tree[id * 2].rc) ans = (ans + ask(id * 2, l, r)) % MOD;
    if (r >= tree[id * 2 + 1].lc) ans = (ans + ask(id * 2 + 1, l, r)) % MOD;

    return ans;
}

void test()//测试用函数
{
    for(int i = 1; i <= n; ++i) printf("%lld ", ask(1, i, i));
}

int main()
{
    scanf("%d%d%lld", &n, &m, &MOD);
    build(1, 1, n);
    //printf("test : ");test();printf("\n");

    while (m--) {
        scanf("%d", &ca1);

        if (ca1 == 1) {
            scanf("%d%d%lld", &ca2, &ca3, &ca4);
            ride(1, ca2, ca3, ca4 % MOD);

            // printf("test : ");test();printf("\n");
        }
        else if (ca1 == 2) {
            scanf("%d%d%lld", &ca2, &ca3, &ca4);
            add(1, ca2, ca3, ca4 % MOD);

            // printf("test : ");test();printf("\n");
        }
        else {
            scanf("%d%d", &ca2, &ca3);
            printf("%lld\n", ask(1, ca2, ca3));
        }
    }

    return 0;
}
2020/11/6 22:51
加载中...