POJ 3261 SA

来源:互联网 发布:移动云商城 源码下载 编辑:程序博客网 时间:2024/05/01 18:58
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define mxn 1002000int s[mxn];int sa[mxn], t[mxn], t2[mxn], c[mxn], n;void get_sa( int m ) {int i, *x = t, *y = t2;for( i = 0; i < m; ++i )c[i] = 0;for( i = 0; i < n; ++i )++c[x[i]=s[i]];for( i = 1; i < m; ++i )c[i] += c[i-1];for( i = n - 1; i >= 0; --i )sa[--c[x[i]]] = i;for( int k = 1; k <= n; k <<= 1 ) {int p = 0;for( i = n - k; i < n; ++i ) y[p++] = i;for( i = 0; i < n; ++i ) if( sa[i] >= k ) y[p++] = sa[i] - k;for( i = 0; i < m; ++i ) c[i] = 0;for( i = 0; i < n; ++i ) c[x[y[i]]] ++;for( i = 1; i < m; ++i ) c[i] += c[i-1];for( i = n - 1; i >= 0; --i ) sa[--c[x[y[i]]]] = y[i];swap( x, y );p = 1;x[sa[0]] = 0;for( int i = 1; i < n; ++i )x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k] ?p - 1: p ++;if( p >= n )break;m = p;}}int Rank[mxn], height[mxn];void get_h() {int i, j, k = 0;for( i = 0; i < n; ++i )Rank[sa[i]] = i;for( i = 0; i < n; ++i ) {if( k ) --k;j = sa[Rank[i]-1];while( s[i+k] == s[j+k] ) ++k;height[Rank[i]] = k;}}int k;bool check( int len ) {int i = 2, cnt;while( 1 ) {while( i < n && height[i] < len ) ++i;if( i >= n )  break;cnt = 1;while( i < n && height[i] >= len ) ++i, ++ cnt;if( cnt >= k )return 1;}return 0;}int main() {while( scanf( "%d%d", &n, &k ) != EOF ) {int mx = 0;for( int i = 0; i < n; ++i ) {scanf( "%d", s + i );s[i] ++;mx = max( mx, s[i] );}s[n++] = 0;get_sa( mx + 1 );get_h();int l = 1, r = n + 1;while( l < r - 1 ) {int mid = ( l + r ) >> 1;if( check( mid ) )l = mid;elser = mid;}printf( "%d\n", l );}return 0;}

0 0
原创粉丝点击