社区讨论

离散化问题求解

P14521【MX-S11-T2】加减乘除参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mi1vb1k3
此快照首次捕获于
2025/11/16 23:25
3 个月前
此快照最后确认于
2025/11/18 10:32
3 个月前
查看原帖
有一个疑惑,我是离散化后用权值树状数组维护,代码如下:
CPP
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, q, len, quest[2000005];
ll arr[5000005];
vector<ll> val;
unordered_map<ll, int> rns;

inline int lowbit(int x) {
    return x & -x;
}

void add(int x, int v) {
    for (int i = x; i <= len; i += lowbit(i))
        arr[i] += v;
}

int que(int x) {
    int ret = 0;
    for (int i = x; i; i -= lowbit(i))
        ret += arr[i];
    return ret;
}

struct edge {
    int to;
    ll l, r;
};
vector<edge> G[500005];

struct node {
    ll op, a, l = 114514, r = -114514;
} a[500005];

pair<ll, ll> ji(ll l1, ll r1, ll l2, ll r2) {
    return make_pair(max(l1, l2), min(r1, r2));
}

void dfs(int u, ll d) {
    for (auto edg : G[u]) {
        int v = edg.to;
        ll l = edg.l - a[u].op * a[u].a;
        ll r = edg.r - a[u].op * a[u].a;
        auto ans = ji(l, r, a[u].l + d, a[u].r + d);
        if (ans.second < ans.first) continue;
        a[v].l = ans.first - d;
        a[v].r = ans.second - d;
        dfs(v, d + a[u].op * a[u].a);
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    // freopen("calc4.in", "r", stdin);
    // freopen("calc.out", "w", stdout);
    cin >> n >> q;
    for (int i = 2; i <= n; ++i) {
        ll f, l, r;
        cin >> f >> l >> r;
        G[f].push_back((edge){i, l, r});
    }
    for (int i = 1; i <= n; ++i) {
        char op;
        cin >> op >> a[i].a;
        a[i].op = (op == '+' ? 1:-1);
    }
    for (int i = 1; i <= q; ++i) {
        cin >> quest[i];
        val.push_back(quest[i]);
    }
    a[1].l = -2e18 - 5, a[1].r = 2e18 + 5;
    dfs(1, 0);
    for (int i = 1; i <= n; ++i) {
        val.push_back(a[i].l);
        val.push_back(a[i].r);
        val.push_back(a[i].r + 1);
    }
    sort(val.begin(), val.end());
    len = unique(val.begin(), val.end()) - val.begin();
    for (int i = 0; i < len; ++i)
        rns[val[i]] = i + 1;
    for (int i = 1; i <= n; ++i) {
        a[i].l = rns[a[i].l];
        a[i].r = rns[a[i].r];
    }
    for (int i = 1; i <= q; ++i)    
        quest[i] = rns[quest[i]];
    for (int i = 1; i <= n; ++i) {
        if (a[i].r < a[i].l)
            continue;
        add(a[i].l, 1);
        add(a[i].r + 1, -1);
    }
    for (int i = 1; i <= q; ++i)
        cout << que(quest[i]) << '\n';
    return 0;
}
由于操作树状数组需要 add(a[i].r + 1, -1); 所以 a[i].r + 1 也需要离散化,但哪怕删除 7777 行也能通过,这是为什么

回复

1 条回复,欢迎继续交流。

正在加载回复...