求可重叠k次的最长子串。
二分子串长度x, 将height数组分组, 看是否有一组中的数量大于等于k。
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <map> 8 #include <set> 9 #include <string> 10 #include <queue> 11 #include <stack> 12 #include <bitset> 13 using namespace std; 14 #define pb(x) push_back(x) 15 #define ll long long 16 #define mk(x, y) make_pair(x, y) 17 #define lson l, m, rt<<1 18 #define mem(a) memset(a, 0, sizeof(a)) 19 #define rson m+1, r, rt<<1|1 20 #define mem1(a) memset(a, -1, sizeof(a)) 21 #define mem2(a) memset(a, 0x3f, sizeof(a)) 22 #define rep(i, n, a) for(int i = a; i<n; i++) 23 #define fi first 24 #define se second 25 typedef pair<int, int> pll; 26 const double PI = acos(-1.0); 27 const double eps = 1e-8; 28 const int mod = 1e9+7; 29 const int inf = 1061109567; 30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 31 const int maxn = 2e4+5; 32 int sa[maxn]; 33 int t1[maxn],t2[maxn],c[maxn], a[maxn]; 34 int rankk[maxn],height[maxn]; 35 void build_sa(int s[],int n,int m) 36 { 37 int i,j,p,*x=t1,*y=t2; 38 for(i=0;i<m;i++)c[i]=0; 39 for(i=0;i<n;i++)c[x[i]=s[i]]++; 40 for(i=1;i<m;i++)c[i]+=c[i-1]; 41 for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i; 42 for(j=1;j<=n;j<<=1) 43 { 44 p=0; 45 for(i=n-j;i<n;i++)y[p++]=i; 46 for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; 47 for(i=0;i<m;i++)c[i]=0; 48 for(i=0;i<n;i++)c[x[y[i]]]++; 49 for(i=1;i<m;i++)c[i]+=c[i-1]; 50 for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i]; 51 swap(x,y); 52 p=1;x[sa[0]]=0; 53 for(i=1;i<n;i++) 54 x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++; 55 if(p>=n)break; 56 m=p; 57 } 58 } 59 void getHeight(int s[],int n) 60 { 61 int i,j,k=0; 62 for(i=0;i<=n;i++)rankk[sa[i]]=i; 63 for(i=0;i<n;i++) 64 { 65 if(k)k--; 66 j=sa[rankk[i]-1]; 67 while(s[i+k]==s[j+k])k++; 68 height[rankk[i]]=k; 69 } 70 } 71 int check(int mid, int n, int m) { 72 int cnt = 1; 73 for(int i = 1; i<=n; i++) { 74 if(height[i]>=mid) { 75 cnt++; 76 if(cnt>=m) 77 return 1; 78 } else { 79 cnt = 1; 80 } 81 } 82 return 0; 83 } 84 int main() 85 { 86 int n, m; 87 while(cin>>n>>m) { 88 int maxx = 0; 89 for(int i = 0; i<n; i++) { 90 scanf("%d", &a[i]); 91 maxx = max(maxx, a[i]); 92 } 93 a[n] = 0; 94 build_sa(a, n+1, maxx+1); 95 getHeight(a, n); 96 int l = 1, r = n, ans; 97 while(l<=r) { 98 int mid = l+r>>1; 99 if(!check(mid, n, m)) { 100 r = mid-1; 101 } else { 102 l = mid+1; 103 ans = mid; 104 } 105 } 106 cout<<ans<<endl; 107 } 108 return 0; 109 }