记录编号 386488 评测结果 AAAAAAAAAAAA
题目名称 [HZOI 2016][NBUT 1653]String in the tree 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 0.998 s
提交时间 2017-03-24 18:07:23 内存使用 5.37 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<queue>
  4. using namespace std;
  5. typedef long long ll;
  6. typedef unsigned int u32;
  7. const int N=1e5+10;
  8. int hash[N],Mi[N];
  9. int n,l[N],r[N],root,len,top,size[N],s[N];
  10. ll tag[N];
  11. int HASH(int i,int l){return hash[i]-hash[i-l]*Mi[l];}
  12. int lcp(int x,int y){
  13. int l=0,r=min(x,y);
  14. while (l<r){
  15. int mid=(l+r)>>1;
  16. if (HASH(x,mid+1)==HASH(y,mid+1)) l=mid+1;else r=mid;
  17. }
  18. return l;
  19. }
  20. bool pre_cmp(int x,int y){
  21. int l=lcp(x,y);
  22. return s[x-l]<s[y-l];
  23. }
  24. int merge(int x,int y){
  25. if (!x||!y) return x|y;
  26. if (size[x]>size[y]){
  27. size[x]+=size[y];
  28. r[x]=merge(r[x],y);
  29. return x;
  30. }
  31. else{
  32. size[y]+=size[x];
  33. l[y]=merge(x,l[y]);
  34. return y;
  35. }
  36. }
  37. int que[N],tail;
  38. void visit(int x){
  39. if (l[x]) visit(l[x]);
  40. que[++tail]=x;
  41. if (r[x]) visit(r[x]);
  42. }
  43. int build(int L,int R,ll le,ll ri){
  44. if (L>R) return 0;
  45. int mid=(L+R)>>1,x=que[mid];
  46. tag[x]=(le+ri)>>1;
  47. l[x]=build(L,mid-1,le,tag[x]);
  48. r[x]=build(mid+1,R,tag[x],ri);
  49. size[x]=R-L+1;
  50. return x;
  51. }
  52. int rebuild(int x,ll L,ll R){
  53. tail=0;visit(x);
  54. return build(1,tail,L,R);
  55. }
  56. int insert(int x,ll L,ll R,int key){
  57. if (!x){
  58. size[++top]=1;
  59. l[top]=r[top]=0;
  60. tag[top]=(L+R)>>1;
  61. return top;
  62. }
  63. size[x]++;
  64. if (pre_cmp(x,key)){
  65. r[x]=insert(r[x],tag[x],R,key);
  66. if (size[r[x]]>0.65*size[x]) x=rebuild(x,L,R);
  67. }
  68. else{
  69. l[x]=insert(l[x],L,tag[x],key);
  70. if (size[l[x]]>0.65*size[x]) x=rebuild(x,L,R);
  71. }
  72. return x;
  73. }
  74. int del(int x,int key){
  75. if (x==key) return merge(l[x],r[x]);
  76. size[x]--;
  77. if (tag[x]<tag[key]) r[x]=del(r[x],key);
  78. else l[x]=del(l[x],key);
  79. return x;
  80. }
  81. int rank(int key){
  82. int x=root,ans=0;
  83. while (1){
  84. int i=size[l[x]]+1;
  85. if (key==x) return ans+i;
  86. tag[x]<tag[key]?x=r[x],ans+=i:x=l[x];
  87. }
  88. }
  89. int find(int R){
  90. int x=root;
  91. while (1){
  92. int i=size[l[x]]+1;
  93. if (R==i) return x;
  94. R>i?x=r[x],R-=i:x=l[x];
  95. }
  96. }
  97. int ans,Ans[N];
  98. void erase(int x){
  99. int R=rank(x),y=find(R-1),z=find(R+1);
  100. ans-=lcp(x,y)+lcp(x,z)-lcp(y,z);
  101. root=del(root,x);
  102. top--;len--;
  103. }
  104. void insert(int w){
  105. s[++len]=w;
  106. hash[len]=hash[len-1]*31+w;
  107. root=insert(root,0,1ll<<62,len);
  108. if (len<3) return;
  109. int R=rank(len),y=find(R-1),z=find(R+1);
  110. ans+=lcp(len,y)+lcp(len,z)-lcp(y,z);
  111. }
  112. vector<int> E[N];
  113. char str[N];
  114. void dfs(int x,int fa){
  115. insert(str[x]-'a'+1);
  116. Ans[x]=(len-1)*(len-2)/2-ans;
  117. for (int i=E[x].size()-1;i>=0;i--)
  118. if (E[x][i]!=fa) dfs(E[x][i],x);
  119. erase(len);
  120. }
  121. int main()
  122. {
  123. freopen("balsuffix.in","r",stdin);
  124. freopen("balsuffix.out","w",stdout);
  125. Mi[0]=1;
  126. for (int i=1;i<N;i++) Mi[i]=Mi[i-1]*31;
  127. insert(27);
  128. insert(0);
  129. int T;scanf("%d",&T);
  130. while (T--){
  131. scanf("%d",&n);
  132. for (int i=1;i<=n;i++) E[i].clear();
  133. for (int i=1;i<n;i++){
  134. int u,v;
  135. scanf("%d%d",&u,&v);
  136. E[u].push_back(v);
  137. E[v].push_back(u);
  138. }
  139. scanf("%s",str+1);
  140. dfs(1,0);
  141. for (int i=1;i<=n;i++) printf("%d\n",Ans[i]);
  142. }
  143. return 0;
  144. }