Submission #1308473

#TimeUsernameProblemLanguageResultExecution timeMemory
1308473Hamed_GhaffariDesignated Cities (JOI19_designated_cities)C++20
100 / 100
551 ms54324 KiB
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

using ll = long long;
using pll = pair<ll, int>;

#define X first
#define Y second
#define mins(a, b) (a = min(a,b))
#define SZ(x) int(x.size())
#define lc id<<1
#define rc lc|1
#define mid ((l+r)>>1)

const int MXN = 2e5+5;

int n, W[MXN<<1], xr[MXN];
vector<int> g[MXN];

bool dead[MXN], mark[MXN];
int sz[MXN];

int dfs_sz(int v, int p) {
    mark[v] = 0;
    sz[v] = 1;
    for(int i : g[v]) {
        int u = v^xr[i>>1];
        if(!dead[u] && u!=p)
            sz[v] += dfs_sz(u, v);
    }
    return sz[v];
}

int centroid(int v, int N, int p) {
    for(int i : g[v]) {
        int u = v^xr[i>>1];
        if(!dead[u] && u!=p && 2*sz[u]>N)
            return centroid(u, N, v);
    }
    return v;
}

int stt[MXN], fnt[MXN], timer, ver[MXN], cmp[MXN], par[MXN];
ll sum[MXN];

void dfs_stt(int v, int p) {
    ver[stt[v] = timer++] = v;
    for(int i : g[v]) {
        int u = v^xr[i>>1];
        if(!dead[u] && u!=p)
            par[u] = i,
            dfs_stt(u, v);
    }
    fnt[v] = timer;
}

pll operator+(pll x, ll y) { return pll(x.X+y, x.Y);}

namespace seg {
    pll seg[MXN<<2];
    ll lz[MXN<<2];
    void build(int l=0, int r=n, int id=1) {
        seg[id] = pll(0, r-1);
        lz[id] = 0;
        if(r-l == 1) return;
        build(l, mid, lc);
        build(mid, r, rc);
    }
    void upd(int s, int e, ll x, int l=0, int r=n, int id=1) {
        if(s>=r || l>=e) return;
        if(s<=l && r<=e) {
            seg[id].X += x;
            lz[id] += x;
            return;
        }
        upd(s, e, x, l, mid, lc);
        upd(s, e, x, mid, r, rc);
        seg[id] = max(seg[lc], seg[rc]) + lz[id];
    }
    pll get(int s, int e, int l=0, int r=n, int id=1) {
        if(s>=r || l>=e) return pll(-1e18, 0);
        if(s<=l && r<=e) return seg[id];
        return max(get(s, e, l, mid, lc), get(s, e, mid, r, rc)) + lz[id];
    }
}

void dfs_cmp(int v, int c, int p) {
    cmp[v] = c;
    sum[v] = 0;
    for(int i : g[v]) {
        int u = v^xr[i>>1];
        if(!dead[u] && u!=p) {
            dfs_cmp(u, c, v);
            sum[v] += sum[u] + W[i];
            seg::upd(stt[u], fnt[u], W[i]);
        }
    }
}

ll ans[MXN];

void solve(int v) {
    mark[v] = 1;
    timer = 0;
    dfs_stt(v, 0);
    seg::build();

    ll tot_sum = 0;
    for(int i : g[v]) {
        int u = v^xr[i>>1];
        if(!dead[u]) {
            dfs_cmp(u, u, v);
            sum[u] += W[i];
            tot_sum += sum[u];
            seg::upd(stt[u], fnt[u], W[i]);
        }
    }

    auto del = [&](int v) -> void {
        while(!mark[v]) {
            seg::upd(stt[v], fnt[v], -W[par[v]]);
            mark[v] = 1;
            v ^= xr[par[v]>>1];
        }
    };

    ll cur = tot_sum;

    for(int i=2; i<=n; i++) {
        if(seg::seg[1].X) {
            cur -= seg::seg[1].X;
            del(ver[seg::seg[1].Y]);
        }
        ans[i] = cur;
    }
}

int V;
ll tot;

void DFS(int v, int p) {
    stt[v] = timer++;
    for(int i : g[v]) {
        int u = v^xr[i>>1];
        if(u==p) continue;
        DFS(u, v);
        tot += W[i];
        seg::upd(stt[u], fnt[u], W[i]);
    }
    fnt[v] = timer;
}

void reroot(int v, int p) {
    mins(ans[1], tot);
    if(ans[2]>tot-seg::seg[1].X) {
        ans[2] = tot-seg::seg[1].X;
        V = v;
    }
    for(int i : g[v]) {
        int u = v^xr[i>>1];
        if(u==p) continue;
        seg::upd(stt[u], fnt[u], -W[i]-W[i^1]);
        seg::upd(0, n, W[i^1]);
        tot += W[i^1]-W[i];
        reroot(u, v);
        tot += W[i]-W[i^1];
        seg::upd(stt[u], fnt[u], W[i]+W[i^1]);
        seg::upd(0, n, -W[i^1]);
    }
}

int32_t main() {
    cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0);
    cin >> n;
    for(int i=0,a,b,c,d; i<n-1; i++) {
        cin >> a >> b >> c >> d;
        g[a].push_back(i<<1); W[i<<1] = c;
        g[b].push_back(i<<1|1); W[i<<1|1] = d;
        xr[i] = a^b;
    }
    seg::build();
    ans[1] = 1e18, ans[2] = 1e18;
    DFS(1, 0);
    reroot(1, 0);
    if(n>=3) solve(V);
    int q;
    cin >> q;
    while(q--) {
        int e;
        cin >> e;
        cout << ans[e] << '\n';
    }
    return 0;
}
#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...