【bzoj3998】[TJOI2015]弦论

来源:互联网 发布:图像测量软件 编辑:程序博客网 时间:2024/06/03 22:11

题目描述:

对于一个给定长度为N的字符串,求它的第K小子串是什么。

样例输入:

aabc
0 3

样例输出:

aab

题解:

构造后缀自动机,然后在后缀自动机上跑dfs

代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#ifdef WIN32#define LL "%I64d"#else#define LL "%lld"#endif#ifdef CT#define debug(...) printf(__VA_ARGS__)#else#define debug(...)#endif#define R register#define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)#define gmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))#define gmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)char B[1<<15],*S=B,*T=B;inline int FastIn(){R char ch;R int cnt=0;R bool minus=0;while (ch=getc(),(ch < '0' || ch > '9') && ch != '-') ;ch == '-' ?minus=1:cnt=ch-'0';while (ch=getc(),ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';return minus?-cnt:cnt;}#define maxn 1000010char str[maxn];int a[maxn][26] , val[maxn] , fa[maxn] , l[maxn] ,last , tot , p , np , q , nq , t , k ;int v[maxn] , que[maxn] , sum[maxn] ;inline void extend (R int c){p = last ;np = last = ++tot ;l[np] = l[p] + 1 ;val[np] = 1;for ( ; !a[p][c] && p ; ) a[p][c] = np , p = fa[p] ;if (!p) fa[np] = 1 ;else{q = a[p][c] ;if (l[p] + 1 == l[q] ) fa[np] = q ;else{nq = ++tot ;l[nq] = l[p] + 1 ;memcpy ( a[nq] , a[q] ,sizeof (a[q]) );fa[nq] = fa[q] ;fa[np] = fa[q] = nq ;for ( ; a[p][c]==q ; ) a[p][c] = nq , p = fa[p] ;}}}inline void prepare(){for (R int i = 1 ; i <= tot ; i++ ) v[ l[i] ] ++ ;for (R int i = 1 ; str[i] ; i++ ) v[i] += v[i-1] ;for (R int i = tot ; i ; i-- ) que [ v[ l[i] ] -- ] = i ;for (R int i = tot ; i ; i-- ){R int tmp = que[i];if (t == 1) val[fa[tmp]] += val[tmp] ;else val[tmp] = 1 ;}val[1] = 0 ;for (R int i = tot ; i ; i--){R int tmp = que[i] ;sum[tmp] = val[tmp] ;for (R int j = 0 ; j < 26 ; j++ )sum[tmp] += sum [ a[tmp][j] ] ;}}void dfs(R int x , R int k){if (k <= val [x] ) return ;k -= val[x] ;for (R int i = 0 ; i < 26 ; i++ ){if (int tmp = a[x][i] ){if (k <= sum[tmp] ){printf("%c" , i + 'a' );dfs(tmp , k);return ;}k -= sum[tmp];}}}int main(){last = ++ tot;scanf ( "%s\n", str + 1);scanf( "%d %d" , &t , &k);for (R int i = 1 ; str[i] ; i++) extend( str[i] - 'a');prepare();if ( sum[1] < k) puts("-1") ;else dfs(1 , k ) ;return 0;}/*aasdfsdafsdafsadfasdfsadf0 4aasd*/


0 0
原创粉丝点击