Submission #995841

#TimeUsernameProblemLanguageResultExecution timeMemory
995841imarnRoad Closures (APIO21_roads)C++14
100 / 100
286 ms59812 KiB
#include<bits/stdc++.h>
#define f first
#define s second
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define sz(x) (int)x.size()
#define all(x) x.begin(),x.end()
#define vi vector<int>
#define vvi vector<vi>
#define vll vector<ll>
using namespace std;
const int mxn=1e5+5;
vector<pii>g[mxn],gr[mxn];int d[mxn]{0};ll s1[mxn]{0};
vll fw[mxn][2],val[mxn];
void add(int i,ll x,int j){
    int id=upper_bound(val[i].begin(),val[i].end(),x)-val[i].begin();
    for(;id<fw[i][0].size();id+=id&-id)fw[i][0][id]+=j,fw[i][1][id]+=x*j;
}
pll qr(int i,ll x,ll rs=0,ll rs2=0){
    int id=upper_bound(val[i].begin(),val[i].end(),x)-val[i].begin();
    for(;id;id-=id&-id)rs+=fw[i][0][id],rs2+=fw[i][1][id];
    return {rs,rs2};
}
ll dp[mxn][2]{0};
vi node;bool use[mxn]{0};
void solve(int u,int p,int k){
    vector<ll>v0;int pr=-1;ll sm=0;use[u]=1;
    for(auto v:gr[u]){
        if(v.f==p){pr=v.s;continue;}
        solve(v.f,u,k);v0.pb(dp[v.f][0]-dp[v.f][1]);sm+=dp[v.f][1];
    }dp[u][0]=s1[u]+sm+(pr==-1?0:pr);if(pr!=-1)v0.pb(-pr);
    sort(v0.begin(),v0.end());
    ll l=-1e15,r=1e15;
    while(l<r){
        ll m=(l+r)>>1;
        int id1=qr(u,m).f;
        int id2=upper_bound(v0.begin(),v0.end(),m)-v0.begin();
        if(id1+id2>=k)r=m;
        else l=m+1;
    }pll x=qr(u,l);dp[u][0]+=x.s;int mem=0;
    for(int i=0;i<v0.size();i++)if(v0[i]<=l)mem=i+1,dp[u][0]+=v0[i];
    dp[u][0]-=l*(mem+x.f-k);if(pr==-1)return;
    for(int i=0;i<v0.size();i++)if(v0[i]==-pr)mem=i;
    swap(v0[mem],v0.back());v0.pop_back();dp[u][1]=s1[u]+sm+pr;sort(v0.begin(),v0.end());
    l=-1e15,r=1e15;
    while(l<r){
        ll m=(l+r)>>1;
        int id1=qr(u,m).f;
        int id2=upper_bound(v0.begin(),v0.end(),m)-v0.begin();
        if(id1+id2>=k)r=m;
        else l=m+1;
    }x=qr(u,l);dp[u][1]+=x.s;mem=0;
    for(int i=0;i<v0.size();i++)if(v0[i]<=l)mem=i+1,dp[u][1]+=v0[i];
    dp[u][1]-=l*(mem+x.f-k);
 
}
vll minimum_closure_costs(int N,vi U,vi V,vi W){vll ans(N,0);ll res=0,tt=0;
    for(int i=0;i<N-1;i++)g[U[i]].pb({V[i],W[i]}),g[V[i]].pb({U[i],W[i]}),d[U[i]]++,d[V[i]]++,tt+=W[i];
    for(int i=0;i<N;i++)for(auto v:g[i])s1[i]+=v.s,val[i].pb(-v.s);
    for(int i=0;i<N;i++){
        sort(val[i].begin(),val[i].end()),fw[i][0].resize(val[i].size()+2),fw[i][1].resize(val[i].size()+2);
        for(auto it : val[i])add(i,it,1);
    }
    vector<pii>ed;for(int i=0;i<N-1;i++)ed.pb({min(d[U[i]],d[V[i]]),i});sort(ed.begin(),ed.end());
    priority_queue<pii>pq;for(int i=0;i<N;i++)pq.push({d[i],i});
    for(int k=N-1;k>=1;k--){
        while(!pq.empty()&&pq.top().f>k)node.pb(pq.top().s),pq.pop();
        while(!ed.empty()&&ed.back().f>k){
            int i=ed.back().s;ed.pop_back();
            gr[U[i]].pb({V[i],W[i]});gr[V[i]].pb({U[i],W[i]});
            s1[U[i]]-=W[i];s1[V[i]]-=W[i];add(U[i],-W[i],-1);
            add(V[i],-W[i],-1);
        }
        for(auto it:node)if(!use[it])solve(it,it,k),res+=dp[it][0];
        for(auto it:node)use[it]=0,dp[it][0]=dp[it][1]=0;
        ans[k]=res;res=0;
    }ans[0]=tt;
    return ans;
}

Compilation message (stderr)

roads.cpp: In function 'void add(int, long long int, int)':
roads.cpp:19:12: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   19 |     for(;id<fw[i][0].size();id+=id&-id)fw[i][0][id]+=j,fw[i][1][id]+=x*j;
      |          ~~^~~~~~~~~~~~~~~~
roads.cpp: In function 'void solve(int, int, int)':
roads.cpp:43:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   43 |     for(int i=0;i<v0.size();i++)if(v0[i]<=l)mem=i+1,dp[u][0]+=v0[i];
      |                 ~^~~~~~~~~~
roads.cpp:45:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   45 |     for(int i=0;i<v0.size();i++)if(v0[i]==-pr)mem=i;
      |                 ~^~~~~~~~~~
roads.cpp:55:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   55 |     for(int i=0;i<v0.size();i++)if(v0[i]<=l)mem=i+1,dp[u][1]+=v0[i];
      |                 ~^~~~~~~~~~
#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...