BZOJ2117: [2010国家集训队]Crash的旅游计划
裸点分,点分树每层维护有序表,查询二分,复杂度$O(nlog^3n)$。
#include<bits/stdc++.h> #define M (u+v>>1) #define pb push_back #define FOR(i,v)\ for(int i=0;i!=v.size();++i) using namespace std; void eq2(int&x,int y){x=x<y?y:x;} const int N=1e5+5; typedef int arr[N]; arr r,z,p,d,c[18]; typedef vector<int>lis; typedef lis arc[N]; arc e1,e2,e3,f1,f2; #define j e1[u][i] void dfs1(int u,int v){ r[u]=1; FOR(i,e1[u]) if(j^v&&!z[j]) dfs1(j,u),r[u]+=r[j]; } int dfs2(int u,int v,int k){ int s=k-r[u]; FOR(i,e1[u]) if(j^v&&!z[j]){ if(int l=dfs2(j,u,k))return l; eq2(s,r[j]); } return s*2<=k?u:0; } int dfs3(int u){ dfs1(u,0),u=dfs2(u,0,r[u]); z[u]=1; FOR(i,e1[u]) if(!z[j])e3[u].pb(dfs3(j)); return u; } void dfs4(int u,int v,int*f){ FOR(i,e1[u]) if(j^v&&z[j]) f[j]=f[u]+e2[u][i],dfs4(j,u,f); } void dfs5(int u,int v,int*f,lis&s){ s.pb(f[u]); FOR(i,e1[u]) if(j^v&&z[j])dfs5(j,u,f,s); } #undef j #define j e3[u][i] void pre(lis&s){sort(s.begin(),s.end());} void dfs6(int u){ int*s=c[d[u]]; dfs4(u,0,s),dfs5(u,0,s,f1[u]),pre(f1[u]),z[u]=0; FOR(i,e3[u]) dfs5(j,0,s,f2[j]),pre(f2[j]),d[j]=d[p[j]=u]+1,dfs6(j); } #undef j int ask(lis&s,int v){return upper_bound(s.begin(),s.end(),v)-s.begin();} int ask(int s,int t){ int i=s,j=d[s],k=ask(f1[s],t)-1; for(;j--;i=p[i]) k+=ask(f1[p[i]],t-c[j][s])-ask(f2[i],t-c[j][s]); return k; } int main(){ int n,k,u,v,w; scanf("%*s%d%d",&n,&k); for(int i=2;i<=n;++i){ scanf("%d%d%d",&u,&v,&w); e1[u].pb(v),e1[v].pb(u); e2[u].pb(w),e2[v].pb(w); } dfs6(dfs3(1)); for(int i=1;i<=n;++i){ u=0,v=1e9; while(u^v)ask(i,M)<k?u=M+1:v=M; printf("%d\n",v); } }