Submission #825336

#TimeUsernameProblemLanguageResultExecution timeMemory
825336vjudge1Designated Cities (JOI19_designated_cities)C++17
100 / 100
510 ms74892 KiB
#include <bits/stdc++.h>
using namespace std;

// 123

class segtree_t {
       public:
        segtree_t *left, *right;
        int l, r, m, id;
        int64_t val, lazy;

        segtree_t(int l, int r) : l(l), r(r), m(l + r >> 1), id(l), val(0), lazy(0) {
                if (l == r) return;
                left = new segtree_t(l, m);
                right = new segtree_t(m + 1, r);
        }

        void Update(int s, int t, int64_t x) {
                if (r < s or l > t) return;
                if (s <= l && r <= t) {
                        val += x;
                        lazy += x;
                        return;
                }
                Down();
                left->Update(s, t, x);
                right->Update(s, t, x);
                Up();
        }

        pair<int64_t, int> Get(int s, int t) {
                if (r < s or l > t) return pair<int64_t, int>(-1, -1);
                if (s <= l && r <= t) return pair<int64_t, int>(val, id);
                Down();
                return max(left->Get(s, t), right->Get(s, t));
        }

        void Up() {
                if (left->val < right->val) {
                        val = right->val;
                        id = right->id;
                } else {
                        val = left->val;
                        id = left->id;
                }
        }

        void Down() {
                left->lazy += lazy;
                right->lazy += lazy;
                right->val += lazy;
                left->val += lazy;
                lazy = 0;
        }
};

int32_t main() {
        ios_base::sync_with_stdio(0);
        cin.tie(0);

        int n;
        cin >> n;
        vector<vector<tuple<int, int, int>>> adj(n);
        vector<int> deg(n, 0);
        for (int i = 0; i < n - 1; i++) {
                int u, v, a, b;
                cin >> u >> v >> a >> b;
                u--, v--;
                deg[u]++, deg[v]++;
                adj[u].emplace_back(v, a, b);
                adj[v].emplace_back(u, b, a);
        }

        vector<int64_t> f(n, 0);
        function<void(int, int)> dfs1 = [&](int u, int p) {
                for (auto [v, a, b] : adj[u]) {
                        if (v == p) continue;
                        dfs1(v, u);
                        f[u] += a + f[v];
                }
        };

        vector<int64_t> g(n, 0);
        function<void(int, int)> dfs2 = [&](int u, int p) {
                for (auto [v, a, b] : adj[u]) {
                        if (v == p) continue;
                        g[v] = g[u] - a + b;
                        dfs2(v, u);
                }
        };

        dfs1(0, -1);
        g[0] = f[0];
        dfs2(0, -1);
        int root = min_element(g.begin(), g.end()) - g.begin();

        vector<int64_t> h(n, 0);
        function<void(int, int)> dfs3 = [&](int u, int p) {
                for (auto [v, a, b] : adj[u]) {
                        if (v == p) continue;
                        h[v] = h[u] + a;
                        dfs3(v, u);
                }
        };

        dfs3(root, -1);
        int root2 = max_element(h.begin(), h.end()) - h.begin();
        h[root2] = 0;
        dfs3(root2, -1);
        int64_t best = *max_element(h.begin(), h.end());

        int time = 0;
        vector<int> tin(n), tout(n), par(n, -1), costp(n);

        function<void(int, int)> dfs4 = [&](int u, int p) {
                tin[u] = time++;
                for (auto [v, a, b] : adj[u]) {
                        if (v == p) continue;
                        par[v] = u;
                        costp[v] = a;
                        dfs4(v, u);
                }
                tout[u] = time;
        };
        dfs4(root2, -1);

        vector<int> node(n);
        for (int i = 0; i < n; i++) {
                node[tin[i]] = i;
        }

        segtree_t *tree = new segtree_t(0, time);
        for (int i = 0; i < n; i++) {
                tree->Update(tin[i], tin[i], h[i]);
        }

        vector<int64_t> pref(n);
        pref[0] = g[root2];
        vector<int> vis(n, 0);
        vis[root2] = 1;

        for (int i = 1; i < n; i++) {
                pref[i] = pref[i - 1] - tree->val;
                int x = node[tree->id];
                while (!vis[x]) {
                        vis[x] = 1;
                        tree->Update(tin[x], tout[x] - 1, -costp[x]);
                        x = par[x];
                }
        }
        pref[0] = g[root];

        int q;
        cin >> q;

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

Compilation message (stderr)

designated_cities.cpp: In constructor 'segtree_t::segtree_t(int, int)':
designated_cities.cpp:12:51: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   12 |         segtree_t(int l, int r) : l(l), r(r), m(l + r >> 1), id(l), val(0), lazy(0) {
      |                                                 ~~^~~
designated_cities.cpp: In function 'int32_t main()':
designated_cities.cpp:110:17: warning: unused variable 'best' [-Wunused-variable]
  110 |         int64_t best = *max_element(h.begin(), h.end());
      |                 ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...