Submission #107798

#TimeUsernameProblemLanguageResultExecution timeMemory
107798shayan_pDesignated Cities (JOI19_designated_cities)C++14
100 / 100
761 ms64752 KiB
// Faster! #include<bits/stdc++.h> #define F first #define S second #define PB push_back #define sz(s) int((s).size()) #define bit(n,k) (((n)>>(k))&1) using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; const int maxn=2e5+10,mod=1e9+7; const ll inf=1e17; vector< pair<int,pii> >v[maxn]; ll ans[maxn],f[maxn],g[maxn],Tot; pair<int,ll>pr[maxn]; int n; ll mx[maxn]; int mxid[maxn]; pii seg[maxn]; int C,reseg[maxn]; bool in[maxn]; ll val[4*maxn],lz[4*maxn]; int who[4*maxn]; void _merge(int id){ val[id]=max(val[2*id],val[2*id+1]); if(val[2*id]==val[id]) who[id]=who[2*id]; else who[id]=who[2*id+1]; } void shift(int l,int r,int id){ val[id]+=lz[id]; if(r-l>1){ lz[2*id]+=lz[id]; lz[2*id+1]+=lz[id]; } lz[id]=0; } void build(int l=0,int r=n,int id=1){ lz[id]=0; if(r-l==1){ who[id]=reseg[l]; val[id]=f[reseg[l]]; return; } int mid=(l+r)>>1; build(l,mid,2*id); build(mid,r,2*id+1); _merge(id); } int ask(){ shift(0,n,1); if(val[1]<=0) return -1; return who[1]; } void put(int pos,ll x,int l=0,int r=n,int id=1){ shift(l,r,id); if(r-l==1){ val[id]=x; return; } int mid=(l+r)>>1; if(pos<mid) put(pos,x,l,mid,2*id), shift(mid,r,2*id+1); else put(pos,x,mid,r,2*id+1), shift(l,mid,2*id); _merge(id); } void add(int f,int s,ll x,int l=0,int r=n,int id=1){ if(f>=s || l>=r) return; shift(l,r,id); if(s<=l || r<=f) return; if(f<=l && r<=s) { lz[id]=x; shift(l,r,id); return; } int mid=(l+r)>>1; add(f,s,x,l,mid,2*id); add(f,s,x,mid,r,2*id+1); _merge(id); } void prep(int u,int par=-1){ mx[u]=f[u],mxid[u]=u; seg[u].F=C, reseg[C]=u, C++; for(auto p:v[u]){ if(p.F!=par){ f[p.F]=f[u]+p.S.F; g[p.F]=g[u]+p.S.S; Tot+=p.S.F; pr[p.F]={u,p.S.F}; prep(p.F,u); if(mx[p.F]>mx[u]){ mx[u]=mx[p.F]; mxid[u]=mxid[p.F]; } } } seg[u].S=C; } pair<ll,pii> choose(int u,int par=-1){ pair<ll,pii> ans={Tot-mx[u]+g[u],{u,mxid[u]}}; pair<ll,int> pp={-1,-1}; for(auto p:v[u]){ if(p.F!=par){ ans=min(ans,choose(p.F,u)); if(pp.F!=-1) ans=min(ans, (pair<ll,pii>){Tot-mx[p.F]-pp.F+f[u]+g[u], {mxid[p.F],pp.S} } ); pp=max(pp, (pair<ll,int>){mx[p.F],mxid[p.F]} ); } } return ans; } void solve(int u){ f[u]=g[u]=Tot=C=0,prep(u); memset(in,0,sizeof in); in[u]=1; build(); int pt=1; while(ask()!=-1){ int tmp=ask(); while(in[tmp]==0){ add(seg[tmp].F,seg[tmp].S,-pr[tmp].S); put(seg[tmp].F,0); Tot-=pr[tmp].S; in[tmp]=1; tmp=pr[tmp].F; } ++pt,ans[pt]=min(ans[pt],Tot); } while(pt<n){ ++pt,ans[pt]=min(ans[pt],Tot); } } int main(){ ios_base::sync_with_stdio(false);cin.tie(0); cin>>n; fill(ans,ans+n+1,inf); for(int i=0;i<n-1;i++){ int a,b,c,d;cin>>a>>b>>c>>d; --a,--b; v[a].PB({b,{c,d}}); v[b].PB({a,{d,c}}); } prep(0); for(int i=0;i<n;i++){ ans[1]=min(ans[1],Tot-f[i]+g[i]); } pii p=choose(0).S; solve(p.F); int q;cin>>q; while(q--){ int x;cin>>x; cout<<ans[x]<<"\n"; } return 0; } // Deathly mistakes: // * Read the problem curfully. // * Check maxn. // * Overflows.
#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...