我的线段树需要 8 倍空间!

学术版

I_Love_DS @ 2024-11-28 21:45:17

为什么?

#include <bits/stdc++.h>

using namespace std;

const int N = 60050;

int n, m, q;

struct SegmentTree {
    int v, tag;
} t[8 * N];

void pushdown(int k) {
    int x = t[k].tag;
    if (!x) return;
    t[k + k].v -= x;
    t[k + k].tag += x;
    t[k + k + 1].v -= x;
    t[k + k + 1].tag += x;
    t[k].tag = 0;
}

void pushup(int k) {
    t[k].v = min(t[k + k].v, t[k + k + 1].v);
}

void buildtree(int k, int l, int r) {
    if (l == r) {
        t[k].v = m;
        t[k].tag = 0;
        return;
    }
    int m = (l + r) / 2;
    buildtree(k + k, l, m);
    buildtree(k + k + 1, m + 1, r);
    pushup(k);
}

void insert(int k, int l, int r, int x, int y, int z) {
    if (l == x && r == y) {
        t[k].v -= z;
        t[k].tag += z;
        pushdown(k);
        //cerr << k << " " << t[k].v << endl;
        return;
    }
    pushdown(k);
    int m = (l + r) / 2;
    if (y <= m) insert(k + k, l, m, x, y, z);
    else if (x > m) insert(k + k + 1, m + 1, r, x, y, z);
    else insert(k + k, l, m, x, m, z), insert(k + k + 1, m + 1, r, m + 1, y, z);
    pushup(k);
    //cerr << k << " " << t[k].v << endl;
}

int calc(int k, int l, int r, int x, int y) {
    if (l == x && r == y) return t[k].v;
    pushdown(k);
    int m = (l + r) / 2, ans = 1 << 30;
    if (y <= m) ans = calc(k + k, l, m, x, y);
    else if (x > m) ans = calc(k + k + 1, m + 1, r, x, y);
    else ans = min(calc(k + k, l, m, x, m), calc(k + k + 1, m + 1, r, m + 1, y));   
    pushup(k);
    return ans;
}

int main() {
    scanf("%d%d%d", &n, &m, &q);
    --n;
    buildtree(1, 1, n);
    while (q--) {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        --y;
        int d = calc(1, 1, n, x, y);
        //cerr << d << endl;
        if (d < z) printf("N\n");
        else {
            printf("T\n");
            insert(1, 1, n, x, y, z);
        }
    }
    return 0;
}

by ragwort @ 2024-11-28 21:47:19

@I_Love_DS 哪道题


by qazsedcrfvgyhnujijn @ 2024-11-28 21:48:05

如果是模板题的话,注意到数据范围是 10^5 量级的


by Brilliant11001 @ 2024-11-28 21:48:23

@I_Love_DS pushdown 到叶子节点了


by BeBanned @ 2024-11-28 21:48:42

有可能你 MAXN 本身设小了。


by I_Love_DS @ 2024-11-28 21:49:04

@qazsedcrfvgyhnujijn

60000 没有任何问题。

@ragwort

https://www.luogu.com.cn/problem/P8856


by 123456xwd @ 2024-11-28 21:49:06

你似乎对叶子节点也进行了 push_down 操作?


by PRIMITIVE_LIGHTS @ 2024-11-28 21:49:17

void insert(int k, int l, int r, int x, int y, int z) {
...
    if (l == x && r == y) {
        t[k].v -= z;
        t[k].tag += z;
        pushdown(k);
        //cerr << k << " " << t[k].v << endl;
        return;
    }
...
}

这里push_down 会导致在叶子节点传标记给不存在的点 删掉就行了


by Loser_Syx @ 2024-11-28 21:49:32

@I_Love_DS 你被包含的区间为啥还要 pushdown


by light_searcher @ 2024-11-28 21:49:36

@I_Love_DS 叶子结点也pushdown了


by I_Love_DS @ 2024-11-28 21:49:56

@Loser_Syx

个人习惯问题,此贴结。


|