记录编号 9734 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [POI 2000] 最长公共子串 最终得分 100
用户昵称 GravatarBYVoid 是否通过 通过
代码语言 C++ 运行时间 0.046 s
提交时间 2009-04-16 20:55:58 内存使用 0.78 MiB
显示代码纯文本
  1. /*
  2. * Problem: POI2000 pow
  3. * Author: Guo Jiabao
  4. * Time: 2009.4.16 19:22
  5. * State: Unsolved
  6. * Memo: 多串最长公共子串 后缀数组 二分答案
  7. */
  8. #include <iostream>
  9. #include <cstdio>
  10. #include <cstdlib>
  11. #include <cmath>
  12. #include <cstring>
  13. const int MAXL=10011,MAXN=6;
  14. using namespace std;
  15. struct SuffixArray
  16. {
  17. struct RadixElement
  18. {
  19. int id,k[2];
  20. }RE[MAXL],RT[MAXL];
  21. int N,A[MAXL],SA[MAXL],Rank[MAXL],Height[MAXL],C[MAXL];
  22. void RadixSort()
  23. {
  24. int i,y;
  25. for (y=1;y>=0;y--)
  26. {
  27. memset(C,0,sizeof(C));
  28. for (i=1;i<=N;i++) C[RE[i].k[y]]++;
  29. for (i=1;i<MAXL;i++) C[i]+=C[i-1];
  30. for (i=N;i>=1;i--) RT[C[RE[i].k[y]]--]=RE[i];
  31. for (i=1;i<=N;i++) RE[i]=RT[i];
  32. }
  33. for (i=1;i<=N;i++)
  34. {
  35. Rank[ RE[i].id ]=Rank[ RE[i-1].id ];
  36. if (RE[i].k[0]!=RE[i-1].k[0] || RE[i].k[1]!=RE[i-1].k[1])
  37. Rank[ RE[i].id ]++;
  38. }
  39. }
  40. void CalcSA()
  41. {
  42. int i,k;
  43. RE[0].k[0]=-1;
  44. for (i=1;i<=N;i++)
  45. RE[i].id=i,RE[i].k[0]=A[i],RE[i].k[1]=0;
  46. RadixSort();
  47. for (k=1;k+1<=N;k*=2)
  48. {
  49. for (i=1;i<=N;i++)
  50. RE[i].id=i,RE[i].k[0]=Rank[i],RE[i].k[1]=i+k<=N?Rank[i+k]:0;
  51. RadixSort();
  52. }
  53. for (i=1;i<=N;i++)
  54. SA[ Rank[i] ]=i;
  55. }
  56. void CalcHeight()
  57. {
  58. int i,k,h=0;
  59. for (i=1;i<=N;i++)
  60. {
  61. if (Rank[i]==1)
  62. h=0;
  63. else
  64. {
  65. k=SA[Rank[i]-1];
  66. if (--h<0) h=0;
  67. for (;A[i+h]==A[k+h];h++);
  68. }
  69. Height[Rank[i]]=h;
  70. }
  71. }
  72. }SA;
  73. int N,Ans,Bel[MAXL];
  74. char S[MAXL];
  75. void init()
  76. {
  77. int i;
  78. freopen("pow.in","r",stdin);
  79. freopen("pow.out","w",stdout);
  80. scanf("%d",&N);
  81. SA.N=0;
  82. for (i=1;i<=N;i++)
  83. {
  84. scanf("%s",S);
  85. for (char *p=S;*p;p++)
  86. {
  87. SA.A[++SA.N]=*p-'a'+1;
  88. Bel[SA.N]=i;
  89. }
  90. if (i<N)
  91. SA.A[++SA.N]=30+i;
  92. }
  93. }
  94. bool check(int A)
  95. {
  96. int i,j,k;
  97. bool ba[MAXN];
  98. for (i=1;i<=SA.N;i++)
  99. {
  100. if (SA.Height[i]>=A)
  101. {
  102. for (j=i;SA.Height[j]>=A && j<=SA.N;j++);
  103. j--;
  104. memset(ba,0,sizeof(ba));
  105. for (k=i-1;k<=j;k++)
  106. ba[Bel[SA.SA[k]]]=true;
  107. for (k=1;ba[k] && k<=N;k++);
  108. if (k==N+1)
  109. return true;
  110. i=j;
  111. }
  112. }
  113. return false;
  114. }
  115. void solve()
  116. {
  117. int a,b,m;
  118. SA.CalcSA();
  119. SA.CalcHeight();
  120. a=0;b=SA.N;
  121. while (a+1<b)
  122. {
  123. m=(a+b)/2;
  124. if (check(m))
  125. a=m;
  126. else
  127. b=m-1;
  128. }
  129. if (check(b))
  130. a=b;
  131. Ans=a;
  132. }
  133. int main()
  134. {
  135. init();
  136. solve();
  137. printf("%d\n",Ans);
  138. return 0;
  139. }