记录编号 281462 评测结果 AAAAAAAAAA
题目名称 [HNOI 2014]世界树 最终得分 100
用户昵称 Gravatar神利·代目 是否通过 通过
代码语言 C++ 运行时间 1.292 s
提交时间 2016-07-11 19:23:00 内存使用 24.32 MiB
显示代码纯文本
  1. #include<stdio.h>
  2. #include<algorithm>
  3. #define N 300010
  4. #define inf 1000000000
  5. int n,x,y,Q,m;
  6. int shu,first[N];
  7. struct edge{int v,nx;}o[N<<1];
  8. inline void add(int u,int v){o[++shu].v=v,o[shu].nx=first[u],first[u]=shu;}
  9. int cnt,fa[N],size[N],dep[N],ord[N],son[N],top[N],seq[N];
  10. int a[N],b[N],Fa[N],X[N],Y[N],st[N],p[N],Ans[N],val[N];
  11. inline bool cmp(int x,int y){return ord[x]<ord[y];}
  12. inline void dfs(int x){
  13. dep[x]=dep[fa[x]]+1,size[x]=1;
  14. for(int i=first[x];i;i=o[i].nx){
  15. if(o[i].v==fa[x])continue;
  16. fa[o[i].v]=x,dfs(o[i].v),size[x]+=size[o[i].v];
  17. if(size[o[i].v]>size[son[x]])son[x]=o[i].v;
  18. }
  19. }
  20. inline void dfs(int x,int y){
  21. top[x]=y,ord[x]=++cnt,seq[cnt]=x;
  22. if(son[x])dfs(son[x],y);
  23. for(int i=first[x];i;i=o[i].nx){
  24. if(o[i].v==fa[x]||o[i].v==son[x])continue;
  25. dfs(o[i].v,o[i].v);
  26. }
  27. }
  28. inline int lca(int x,int y){
  29. for(;top[x]!=top[y];x=fa[top[x]])
  30. if(dep[top[x]]<dep[top[y]])std::swap(x,y);
  31. return dep[x]<dep[y]?x:y;
  32. }
  33. inline int get(int x,int d){
  34. for(;dep[top[x]]>d;x=fa[top[x]]);
  35. return seq[ord[x]-dep[x]+d];
  36. }
  37. inline void Min(int x,int y,int z){
  38. if(X[x]>X[y]+z||(X[x]==X[y]+z&&Y[x]>Y[y]))
  39. X[x]=X[y]+z,Y[x]=Y[y];
  40. }
  41. int main(){
  42. freopen("worldtree.in","r",stdin);
  43. freopen("worldtree.out","w",stdout);
  44. scanf("%d",&n);
  45. for(int i=1;i<n;++i)scanf("%d%d",&x,&y),add(x,y),add(y,x);
  46. dfs(1),dfs(1,1);
  47. for(scanf("%d",&Q);Q--;){
  48. int cnt=0;
  49. scanf("%d",&m);
  50. for(int i=1;i<=m;++i)scanf("%d",&a[i]),p[++cnt]=b[i]=a[i],X[a[i]]=0,Y[a[i]]=a[i];
  51. std::sort(a+1,a+m+1,cmp);
  52. for(int i=1,tail=0;i<=m;++i)if(tail){
  53. int t=lca(st[tail],a[i]);
  54. for(;dep[st[tail]]>dep[t];--tail)
  55. if(dep[st[tail-1]]<=dep[t])Fa[st[tail]]=t;
  56. if(st[tail]!=t)Fa[t]=st[tail],st[++tail]=p[++cnt]=t,X[t]=inf,Y[t]=0;
  57. st[++tail]=a[i],Fa[a[i]]=t;
  58. }else st[++tail]=a[i],Fa[a[i]]=0;
  59. std::sort(p+1,p+cnt+1,cmp);
  60. for(int i=cnt;i>1;--i)Min(Fa[p[i]],p[i],dep[p[i]]-dep[Fa[p[i]]]);
  61. for(int i=2;i<=cnt;++i)Min(p[i],Fa[p[i]],dep[p[i]]-dep[Fa[p[i]]]);
  62. for(int i=1;i<=cnt;++i){
  63. x=p[i],y=Fa[x],val[x]=size[x];
  64. if(i==1){
  65. Ans[Y[x]]+=n-size[x];
  66. continue;
  67. }
  68. int t=get(x,dep[y]+1),sum=size[t]-size[x];
  69. val[y]-=size[t];
  70. if(Y[x]==Y[y]){
  71. Ans[Y[x]]+=sum;
  72. continue;
  73. }
  74. t=X[x]-X[y]+dep[x]+dep[y]+2;
  75. if(t&1^1&&Y[y]>Y[x])t-=2;
  76. t>>=1;
  77. t=size[get(x,t)]-size[x];
  78. Ans[Y[x]]+=t,Ans[Y[y]]+=sum-t;
  79. }
  80. for(int i=1;i<=cnt;++i)
  81. Ans[Y[p[i]]]+=val[p[i]];
  82. for(int i=1;i<=m;++i)printf("%d ",Ans[b[i]]),Ans[b[i]]=0;
  83. puts("");
  84. }
  85. }
  86.