指针又一次被我写挂了。。(一定要记得循环出去后一定得更新一下答案)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
const lint maxn = 20005;
const lint log_maxn = 20;
typedef int lint;
struct suffix{
int c[maxn],sa[maxn],t1[maxn],t2[maxn],m,n,h[maxn],height[maxn],rk[maxn],s[maxn];
void Build_SA(int len){
m = 0;
int* x = t1,*y = t2;
n = len;
for( int i = 0;i < n;i++ ) m = max( m,s[i] );
for( int i = 0;i <= m;i++ ) c[i] = 0;
for( int i = 0;i < n;i++ ) c[ x[i] = s[i] ]++;
for( int i = 1;i <= m;i++ ) c[i] += c[i-1];
for( int i = n-1;i >= 0;i-- ) {
sa[ --c[ x[i] ] ] = i;
}
for( int k = 1;k < n;k <<= 1 ){
int cnt = 0;
for( int i = n - 1;i >= n-k;i-- ) y[cnt++] = i;
for( int i = 0;i < n;i++ ) if( sa[i] >= k ) y[cnt++] = sa[i]-k;
for( int i = 0;i <= m;i++ ) c[i] = 0;
for( int i = 0;i < n;i++ ) c[ x[i] ]++;
for( int i = 1;i <= m;i++ ) c[i] += c[i-1];
for( int i = cnt-1;i >= 0;i-- ) sa[ --c[ x[ y[i] ] ] ] = y[i];
swap( x,y );
int num = 0;
x[ sa[0] ] = 0;
for( int i = 1;i < n;i++ ){
if( y[ sa[i-1] ] != y[ sa[i] ] || y[ sa[i-1]+k ] != y[ sa[i]+k ] ){
x[ sa[i] ] = ++num;
}else{
x[ sa[i] ] = num;
}
}
if( num == n-1 ) return;
m = num;
}
}
void getheight(){
for( int i = 0;i < n;i++ ){
rk[ sa[i] ] = i;
}
int cnt = 1;
h[ sa[0] ] = 0;
height[ 0 ] = 0;
for( int i = 0;i < n;i++ ){
if(cnt)cnt--;
while( rk[i] >= 1 && i + cnt < n &&sa[rk[i]-1]+cnt < n && s[ sa[rk[i]-1]+cnt ] == s[ i+cnt ] ) cnt++;
h[ i ] = cnt;
height[ rk[i] ] = cnt;
}
}
}g;
int judge( int k,int n ){
int cnt = 1;
int mx = -1;
for( int i = 1;i < n;i++ ){
if( g.height[i] >= k ){
cnt++;
}else{
mx = max(mx,cnt );
cnt = 1;
}
}
mx = max( mx,cnt );
return mx;
}
int a[maxn];
vector<int> ve;
void discrete(){
sort( ve.begin(),ve.end() );
ve.erase( unique( ve.begin(),ve.end() ),ve.end() );
}
int h( int x ){
return lower_bound( ve.begin(),ve.end(),x ) - ve.begin();
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for( int i = 0;i < n;i++ )scanf("%d",&a[i]),ve.push_back(a[i]);
discrete();
for( int i = 0;i < n;i++ ) g.s[i] = h(a[i]);
//for( int i = 0;i < n;i++ ) g.s[i] = a[i];
g.Build_SA(n);
g.getheight();
int l = 0,r = n;
while(l!=r-1){
int mid = l+r>>1;
int res = judge(mid,n);
if( res < k ){
r = mid;
}else{
l = mid;
}
}
printf("%d\n",l);
return 0;
}
因篇幅问题不能全部显示,请点此查看更多更全内容