Submission #1308454

#TimeUsernameProblemLanguageResultExecution timeMemory
1308454Hamed_GhaffariDesignated Cities (JOI19_designated_cities)C++20
23 / 100
2097 ms52508 KiB
#include <bits/stdc++.h>
using namespace std;

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;
}

namespace seg {
    int n;
    vector<pll> seg;
    vector<ll> lz;
    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 app(ll x, int id) {
        seg[id].X += x;
        lz[id] += x;
    }
    void push(int id) {
        if(!lz[id]) return;
        app(lz[id], lc);
        app(lz[id], rc);
        lz[id] = 0;
    }
    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) return app(x, id);
        push(id);
        upd(s, e, x, l, mid, lc);
        upd(s, e, x, mid, r, rc);
        seg[id] = max(seg[lc], seg[rc]);
    }
    pll get(int s, int e, int l=0, int r=n, int id=1) {
        if(s>=r || l>=e) return pll(0, 0);
        if(s<=l && r<=e) return seg[id];
        push(id);
        return max(get(s, e, l, mid, lc), get(s, e, mid, r, rc));
    }
}

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]);
        }
    }
}

vector<ll> solve(int v) {
    dead[v = centroid(v, dfs_sz(v, 0), 0)] = 1;
    mark[v] = 1;
    timer = 0;
    dfs_stt(v, 0);
    if(fnt[v]-stt[v]==1) return {0, 0};
    if(fnt[v]-stt[v]==2) {
        vector<ll> ans = {0, ll(1e18), 0};
        for(int i : g[v])
            if(!dead[v^xr[i>>1]])
                ans[1] = min(W[i], W[i^1]);
        return ans;
    }
    int n = fnt[v]-stt[v];
    seg::n = n;
    seg::seg.resize(4*n+5);
    seg::lz.resize(4*n+5);
    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]);
        }
    }
    vector<ll> ans(n+1, 0); ans[1] = tot_sum;

    int cp = cmp[ver[seg::seg[1].Y]];
    bool oth=0;
    auto del = [&](int v) -> void {
        if(cmp[v]!=cp) oth = 1;
        while(!mark[v]) {
            seg::upd(stt[v], fnt[v], -W[par[v]]);
            mark[v] = 1;
            v ^= xr[par[v]>>1];
        }
    };

    ll cur = tot_sum - seg::seg[1].X;
    del(ver[seg::seg[1].Y]);

    for(int i=2; seg::seg[1].X; i++) {
        if(!oth)
            ans[i] = cur-max(seg::get(0, stt[cp]), seg::get(fnt[cp], n)).X;
        cur -= seg::seg[1].X;
        del(ver[seg::seg[1].Y]);
        if(oth) ans[i] = cur;
    }

    for(int i : g[v]) {
        int u = v^xr[i>>1];
        if(dead[u]) continue;
        ll add = tot_sum - sum[u] + W[i^1];
        vector<ll> tmp = solve(u);
        for(int j=1; j<SZ(tmp); j++)
            mins(ans[j], tmp[j]+add);
    }

    return ans;
}

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;
    }
    vector<ll> ans = solve(1);
    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...