社区讨论

求问:为什么加一个等号就对了

P9531[JOIST 2022] 复兴计划 / Reconstruction Project参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@mm0ni6pf
此快照首次捕获于
2026/02/24 21:38
2 周前
此快照最后确认于
2026/02/26 12:45
2 周前
查看原帖
第 95 行的
if (abs(w1 - mid) < abs(w2 - mid)) return nxt[ptl--];
判断条件加一个等号就对了,但是这样不应该是等价的吗?
CPP
#include <bits/stdc++.h>

#define debug(...) fprintf(stderr,__VA_ARGS__)

template <typename type>
inline void read(type &x) {
    x = 0; bool flag (0); char ch = getchar();
    while (!isdigit(ch)) flag = ch == '-', ch = getchar();
    while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    flag ? x = -x : 0;
}
template<typename type>
inline void write(type x, bool mode = 1) {
    x < 0 ? x = -x, putchar('-') : 0; static short Stack[50], top(0);
    do Stack[++top] = x % 10, x /= 10; while (x);
    while (top) putchar(Stack[top--] | 48);
    mode ? putchar('\n') : putchar(' ');
}

using ll = long long;

using namespace std;

constexpr int MaxN = 505;
constexpr int MaxM = 1e5 + 10;
constexpr int MaxQ = 1e6 + 10;
constexpr int MaxV = 1e9;

using Edge = tuple <int, int, int>;

int n, m;
Edge e[MaxM];
int L[MaxM], R[MaxM];

int fa[MaxN];
int find(int x) {
    while (x != fa[x])
        x = fa[x] = fa[fa[x]];
    return x;
}

int bel[MaxM];

void solve(int l, int r, vector <int> edge) {
    // debug(" solve(%d, %d)\n", l, r);
    if (edge.size() == 0) return;
    // debug(" solve(%d, %d) : edge : ", l, r);
    // for (auto i : edge) {
    //     auto [w, u, v] = e[i];
    //     debug("(%d, %d, %d)[%d], ", u, v, w, i);
    // }
    // debug("\n");

    auto Rec = [&](vector <int> &edge, vector <pair <int, int>> &rec) {
        for (auto i : edge) {
            auto [w, u, v] = e[i];
            rec.emplace_back(u, find(u));
            rec.emplace_back(find(u), fa[find(u)]);
            rec.emplace_back(v, find(v));
            rec.emplace_back(find(v), fa[find(v)]);
        }
    };

    vector <pair <int, int>> rec;
    vector <int> nxt;
    Rec(edge, rec);

    const int mid = (l + r) >> 1;
    for (auto i : edge) {
        auto [w, u, v] = e[i];
        if (L[i] <= l && r <= R[i])
            fa[find(u)] = find(v);
        else nxt.emplace_back(i);
    }

    if (nxt.size() == 0) {
        for (auto [u, v] : rec)
            fa[u] = v;
        return;
    }
    
    vector <pair <int, int>> rec1;
    Rec(nxt, rec1);

    int ptl = 0, ptr = 0, siz = nxt.size();
    for (int i = 0; i < siz; i++) if (get<0>(e[nxt[i]]) <= mid)
        ptl = i;
    ptr = ptl + 1;

    auto get_nxt = [&]() {
        if (ptl < 0) return nxt[ptr++];
        if (ptr >= siz) return nxt[ptl--];
        int w1 = get<0>(e[nxt[ptl]]);
        int w2 = get<0>(e[nxt[ptr]]);
        if (abs(w1 - mid) < abs(w2 - mid)) return nxt[ptl--];
        return nxt[ptr++];
    };

    // debug(" calc mst -> %d, siz = %d\n", mid, siz);
    while (ptl >= 0 || ptr < siz) {
        int now = get_nxt();
        auto [w, u, v] = e[now];
        if (find(u) == find(v)) {
            if (w > mid) bel[now] = 2;
            else bel[now] = 1;
        } else {
            // debug("link (%d, %d, %d)\n", u, v, w);
            fa[find(u)] = find(v);
            L[now] = min(L[now], mid);
            R[now] = max(R[now], mid);
            bel[now] = 0;
        }
    }

    if (l < r) {
        // debug(" this\n");
        vector <int> nxt_l, nxt_r;
        for (auto i : nxt) {
            // auto [w, u, v] = e[i];
            // debug(" check (%d, %d, %d) -> bel = %d\n", u, v, w, bel[i]);
            if (bel[i] != 2) nxt_l.emplace_back(i);
            if (bel[i] != 1) nxt_r.emplace_back(i);
        }
        for (auto [u, v] : rec1)
            fa[u] = v;
        solve(l, mid, nxt_l);
        solve(mid + 1, r, nxt_r);
    }
    for (auto [u, v] : rec) fa[u] = v;
}

vector <Edge> in_mst;

signed main() {
    read(n), read(m);
    for (int i = 1; i <= m; i++) {
        auto &[w, u, v] = e[i];
        read(u), read(v), read(w);
    }
    sort(e + 1, e + m + 1);

    for (int i = 1; i <= m; i++)
        L[i] = R[i] = get<0>(e[i]);
    for (int i = 1; i <= n; i++)
        fa[i] = i;
    
    vector <int> tem(m);
    iota(tem.begin(), tem.end(), 1);
    solve(1, MaxV, tem);
    // debug(" solved!");

    for (int i = 1; i <= m; i++) {
        auto [w, u, v] = e[i];
        in_mst.emplace_back(L[i], w, -1);
        in_mst.emplace_back(w, -2 * w, 2);
        in_mst.emplace_back(R[i] + 1, w, -1);
    }
    sort(in_mst.begin(), in_mst.end());

    ll s1 = 0, s2 = 0;
    int now = 0;
    int q; read(q);
    while (q--) {
        int x; read(x);
        while (now < (int)in_mst.size() && get<0>(in_mst[now]) <= x) {
            auto [pos, w, type] = in_mst[now++];
            s1 += w, s2 += type;
        }
        write(s1 + s2 * x);
    }
}

回复

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

正在加载回复...