QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#109402#68. Designated Citiesbashkort0 0ms0kbC++205.7kb2023-05-28 21:57:302023-05-28 21:57:32

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-28 21:57:32]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:0kb
  • [2023-05-28 21:57:30]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

namespace SegmentTree {
    constexpr int N_ = 1 << 19;
    pair<ll, int> t[N_];
    int sz = 1;

    void init(int n, vector<ll> dist) {
        sz = 1 << __lg(n) + !!(n & (n - 1));
        for (int i = 0; i < n; ++i) {
            t[i + sz] = {dist[i], i};
        }
        for (int i = sz - 1; i > 0; --i) {
            t[i] = max(t[i << 1], t[i << 1 | 1]);
        }
    }

    void modify(int x) {
        t[x += sz].first = 0;
        while (x >>= 1) {
            t[x] = max(t[x << 1], t[x << 1 | 1]);
        }
    }

    pair<ll, int> rangeMax(int l, int r, int x = 1, int lx = 0, int rx = sz) {
        if (l >= rx || lx >= r) {
            return {};
        }
        if (l <= lx && rx <= r) {
            return t[x];
        }
        int mid = lx + rx >> 1;
        return max(rangeMax(l, r, x << 1, lx, mid), rangeMax(l, r, x << 1 | 1, mid, rx));
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    vector<vector<pair<int, int>>> adj(n);
    vector<int> A(n), B(n), C(n), D(n);

    for (int i = 0; i < n - 1; ++i) {
        cin >> A[i] >> B[i] >> C[i] >> D[i];
        --A[i], --B[i];
        adj[A[i]].emplace_back(B[i], i);
        adj[B[i]].emplace_back(A[i], i);
    }

    auto cost = [&](int to, int i) {
        return B[i] == to ? C[i] : D[i];
    };

    vector<ll> ans(n + 1);

    auto dij = [&](int source) -> vector<ll> {
        vector<ll> dist(n, -1);
        dist[source] = 0;

        auto dfs = [&](auto self, int v) -> void {
            for (auto [to, i] : adj[v]) {
                if (dist[to] == -1) {
                    dist[to] = dist[v] + cost(to, i);
                    self(self, to);
                }
            }
        };

        dfs(dfs, source);

        return dist;
    };

    vector<ll> dist0 = dij(0);
    vector<ll> sub0(n), cost0(n);

    ll wSum = 0;

    for (int i = 0; i < n - 1; ++i) {
        if (dist0[A[i]] < dist0[B[i]]) {
            cost0[0] += D[i];
        } else {
            cost0[0] += C[i];
        }
        wSum += C[i];
        wSum += D[i];
    }


    auto dfs1 = [&](auto self, int v, int par) -> void {
        ans[1] = max(ans[1], cost0[v]);

        for (auto [to, i] : adj[v]) {
            if (to != par) {
                cost0[to] = cost0[v] - cost(v, i) + cost(to, i);
                self(self, to, v);
                sub0[v] = sub0[v] + sub0[to] + cost(v, i);
            }
        }
    };

    dfs1(dfs1, 0, -1);

    assert(cost0[0] == sub0[0]);

    ans[n] = wSum; //to handle n = 2

    vector<pair<ll, int>> dp(n);

    ll diamDist = -1;
    int dx = -1, dy = -1;

    auto dfs0 = [&](auto self, int v, int par) -> void {
        dp[v] = {dist0[v], v};

        for (auto [to, i] : adj[v]) {
            if (to != par) {
                self(self, to, v);

                if (dp[v].first + dp[to].first - 2 * dist0[v] + cost0[v] > diamDist) {
                    dx = dp[v].second;
                    dy = dp[to].second;
                    diamDist = dp[v].first + dp[to].first - 2 * dist0[v] + cost0[v];
                }

                dp[v] = max(dp[v], dp[to]);
            }
        }
    };

    dfs0(dfs0, 0, -1);

    ans[2] = diamDist;

    vector<int> tin(n), tout(n), ord(n), parent(n);
    vector<ll> depth(n);

    auto dfs = [&](auto self, int v, int par) -> void {
        static int T = 0;
        tin[v] = T++;
        ord[tin[v]] = v;

        for (auto [to, i] : adj[v]) {
            if (to != par) {
                parent[to] = v;
                depth[to] = depth[v] + cost(to, i);
                self(self, to, v);
            }
        }

        tout[v] = T;
    };

    dfs(dfs, dx, -1);

    vector<bool> used(n);
    vector<ll> init(n);

    for (int i = 0; i < n; ++i) {
        init[i] = depth[ord[i]];
    }

    SegmentTree::init(n, init);
    set<array<int, 3>> seg;
    set<pair<ll, int>, greater<>> best;
    map<pair<int, int>, pair<ll, int>> mp;

    auto ins = [&](int l, int r, int v) {
        if (l < r) {
            seg.insert({l, r, v});
            mp[{l, r}] = SegmentTree::rangeMax(l, r);
            mp[{l, r}].first -= depth[v];
            best.emplace(mp[{l, r}]);
        }
    };

    auto er = [&](int l, int r, int v) {
        if (l < r) {
            seg.erase({l, r, v});
            best.erase({mp[{l, r}]});
        }
    };

    auto kill = [&](int v) {
        int l = tin[v], r = tout[v];
        auto it = seg.lower_bound({l + 1, -1});
        if (it != seg.begin()) {
            auto [lx, rx, x] = *prev(it);
            er(lx, rx, x);
            ins(lx, l, x), ins(r, rx, x);
        }
        ins(l, r, v);
    };

    auto choose = [&](int v) {
        auto [l, r, x] = *prev(seg.lower_bound({tin[v] + 1, -1, -1}));
        er(l, r, x);
        SegmentTree::modify(tin[v]);
        ins(l, r, x);
        vector<int> t;
        while (!used[v]) {
            t.push_back(v);
            v = parent[v];
        }
        while (!t.empty()) {
            kill(t.back());
            t.pop_back();
        }
    };

    kill(dx);

    choose(dy);

    int k = 2;
    ll sum = diamDist;

    while (!best.empty()) {
        auto [di, v] = *best.begin();
        if (di <= 0) {
            break;
        }
        k += 1;
        sum += di;
        ans[k] = sum;
        choose(ord[v]);
    }

    for (int i = 1; i <= n; ++i) {
        ans[i] = max(ans[i], ans[i - 1]);
    }
    
    int q;
    cin >> q;

    while (q--) {
        int e;
        cin >> e;
        cout << wSum - ans[e] << '\n';
    }

    return 0;
}

详细

Subtask #1:

score: 0
Memory Limit Exceeded

Test #1:

score: 0
Memory Limit Exceeded

input:

2
1 2 781089648 283888890
2
1
2

output:


result:


Subtask #2:

score: 0
Memory Limit Exceeded

Test #12:

score: 0
Memory Limit Exceeded

input:

2
1 2 683402985 526289818
1
1

output:


result:


Subtask #3:

score: 0
Memory Limit Exceeded

Test #21:

score: 0
Memory Limit Exceeded

input:

2
2 1 92722556 873785501
1
2

output:


result:


Subtask #4:

score: 0
Skipped

Dependency #1:

0%

Subtask #5:

score: 0
Memory Limit Exceeded

Test #45:

score: 0
Memory Limit Exceeded

input:

2
1 2 543195986 144983073
1
1

output:


result:


Subtask #6:

score: 0
Skipped

Dependency #1:

0%