题意:求可相交的重复k次串
思路:后缀数组+二分
1 #include<iostream>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 #define MAXN 20001
6 struct number
7 {
8 int num,id;
9 };
10 number a[MAXN];
11 int b[MAXN];
12 int suffix_array[MAXN];
13 int cnt[MAXN];
14 int tmp[MAXN];
15 int rank[MAXN*2],oldrank[MAXN*2];
16 int height[MAXN];
17 int n,m;
18 bool cmp(const number &x, const number &y)
19 {
20 return x.num<y.num;
21 }
22 void SuffixArray()
23 {
24 int i;
25 memset(rank,0,sizeof(rank));
26 sort(a+1,a+n+1,cmp); a[0].num=-1;
27 int pre=0,j=0;
28 for(i=1;i<=n;i++)
29 {
30 if(a[i].num==a[j].num) rank[a[i].id]=pre;
31 else
32 {
33 pre++; j=i;
34 rank[a[i].id]=pre;
35 }
36 }
37 memset(oldrank,0,sizeof(oldrank));
38 for(int l=1;l<=n;l*=2)
39 {
40 memset(cnt,0,sizeof(cnt));
41 for(i=1;i<=n;i++) cnt[rank[i+l]]++;
42 for(i=1;i<=n;i++) cnt[i]+=cnt[i-1];
43 for(i=1;i<=n;i++) tmp[cnt[rank[i+l]]--]=i;
44
45 memset(cnt,0,sizeof(cnt));
46 for(i=1;i<=n;i++) cnt[rank[tmp[i]]]++;
47 for(i=1;i<=n;i++) cnt[i]+=cnt[i-1];
48 for(i=n;i>0;i--) suffix_array[cnt[rank[tmp[i]]]--]=tmp[i];
49
50 memcpy(oldrank,rank,sizeof(rank));
51 rank[suffix_array[1]]=1;
52 int k=1;
53 for(i=2;i<=n;i++)
54 {
55 int x=suffix_array[i-1],y=suffix_array[i];
56 if(oldrank[x]!=oldrank[y]||oldrank[x+l]!=oldrank[y+l])
57 k++;
58 rank[y]=k;
59 }
60 if(k==n)break;
61 }
62 }
63 void LCP()
64 {
65 int i,j;
66 int k=0;
67 for(i=1;i<=n;i++)
68 {
69 if(rank[i]==n)
70 {
71 height[n]=k=0;
72 continue;
73 }
74 j=suffix_array[rank[i]+1];
75 k=max(k-1,0);
76 while(b[i+k]==b[j+k]) k++;
77 height[rank[i]]=k;
78 }
79 }
80 bool check(int mid)
81 {
82 int k=1;
83 for(int i=1;i<n;i++)
84 {
85 if(height[i]>=mid)
86 k++;
87 else k=1;
88 if(k>=m) return true;
89 }
90 return false;
91 }
92 int binary()
93 {
94 int left,right,mid;
95 left=0; right=n;
96 while(left<right)
97 {
98 mid=(left+right)/2;
99 if(check(mid)) left=mid;
100 else right=mid;
101 if(right-left==1) return left;
102 }
103 }
104 int main()
105 {
106 scanf("%d%d",&n,&m);
107 int i;
108 memset(a,0xff,sizeof(a));
109 for(i=1;i<=n;i++)
110 {
111 scanf("%d",&a[i].num);
112 a[i].id=i;
113 b[i]=a[i].num;
114 }
115 SuffixArray();
116 LCP();
117 printf("%d\n",binary());
118 return 0;
119 }