Submission #973144

#TimeUsernameProblemLanguageResultExecution timeMemory
973144bachhoangxuanRoad Closures (APIO21_roads)C++17
100 / 100
279 ms62776 KiB
#include "roads.h"
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
const ll inf = 1e18;

struct Segtree{
    int sz;
    vector<ll> tree;
    vector<int> cnt;
    vector<pii> com;
    Segtree(){}
    void add(pii val){
        com.push_back(val);
    }
    void build(int l,int r,int id){
        if(l==r){
            tree[id]=com[l-1].fi;
            cnt[id]=1;
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid,id<<1);build(mid+1,r,id<<1|1);
        tree[id]=tree[id<<1]+tree[id<<1|1];
        cnt[id]=cnt[id<<1]+cnt[id<<1|1];
    }
    void update(int l,int r,int id,int p){
        if(l==r){
            tree[id]=cnt[id]=0;
            return;
        }
        int mid=(l+r)>>1;
        if(p<=mid) update(l,mid,id<<1,p);
        else update(mid+1,r,id<<1|1,p);
        tree[id]=tree[id<<1]+tree[id<<1|1];
        cnt[id]=cnt[id<<1]+cnt[id<<1|1];
    }
    ll query(int l,int r,int id,int k){
        if(l==r) return (k>=1)*tree[id];
        int mid=(l+r)>>1;
        if(cnt[id<<1]<k) return tree[id<<1]+query(mid+1,r,id<<1|1,k-cnt[id<<1]);
        else return query(l,mid,id<<1,k);
    }
    void build(){
        sort(com.begin(),com.end(),greater<pii>());
        sz=(int)com.size();
        tree.assign(4*sz,0);
        cnt.assign(4*sz,0);
        build(1,sz,1);
    }
    void del(pii x){
        int pos=lower_bound(com.begin(),com.end(),x,greater<pii>())-com.begin()+1;
        update(1,sz,1,pos);
    }
    ll query(int k){
        return query(1,sz,1,k);
    }
};

std::vector<ll> minimum_closure_costs(int N, vector<int> U,
                                             vector<int> V,
                                             vector<int> W) {
    vector<ll> res(N),total(N);
    vector<vector<pii>> edge(N),adj(N);
    vector<vector<int>> pos(N);
    vector<Segtree> ST(N);
    vector<bool> add(N,false),vis(N,false);

    for(int i=0;i<N-1;i++){
        edge[U[i]].push_back({V[i],W[i]});
        edge[V[i]].push_back({U[i],W[i]});
    }
    for(int i=0;i<N;i++){
        pos[(int)edge[i].size()].push_back(i);
        for(auto [v,w]:edge[i]) ST[i].add({w,v}),total[i]+=w;
        ST[i].build();
    }
    vector<int> cc;
    vector<array<ll,2>> dp(N);
    for(int k=N-1;k>=0;k--){
        for(int u:pos[k]){
            cc.push_back(u);
            for(auto [v,w]:edge[u]){
                total[v]-=w;
                ST[v].del({w,u});
                if(add[v]){
                    adj[u].push_back({v,w});
                    adj[v].push_back({u,w});
                }
            }
            add[u]=true;
        }
        function<void(int)> dfs = [&](int u){
            int C=0;vis[u]=true;
            dp[u][0]=dp[u][1]=inf;
            ll num=total[u];
            vector<ll> val;
            for(auto [v,w]:adj[u]){
                if(vis[v]){C=w;continue;}
                dfs(v);num+=dp[v][0];
                if(dp[v][0]>dp[v][1]) val.push_back(dp[v][0]-dp[v][1]);
            }
            sort(val.begin(),val.end(),greater<ll>());
            ll cur=num;
            for(int i=0;i<=(int)val.size();i++){
                if(i) cur-=val[i-1];
                if(i<=k) dp[u][0]=min(dp[u][0],cur-ST[u].query(k-i)+C);
                if(i<k) dp[u][1]=min(dp[u][1],cur-ST[u].query(k-1-i));
            }
        };
        for(int u:cc) vis[u]=false;
        for(int u:cc) if(!vis[u]){
            dfs(u);
            res[k]+=min(dp[u][0],dp[u][1]);
        }
    }
    return res;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...