码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3998 [TJOI2015]弦论(SAM)

时间:2016-02-19 14:15:22      阅读:263      评论:0      收藏:0      [点我收藏+]

标签:

 

Description

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

Input

 第一行是一个仅由小写英文字母构成的字符串S

第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个。T=1则表示不同位置的相同子串算作多个。K的意义如题所述。

Output

输出仅一行,为一个数字串,为第K小的子串。如果子串数目不足K个,则输出-1

Sample Input

aabc
0 3

Sample Output

aab

HINT

 N<=5*10^5

T<2
K<=10^9

 

【思路】

 

  0的情况和这个题一样每个子串不同位置出现次数算作1;

  至于1,统计val作为该子串在不同位置出现的次数,相应修改一下就可以了。

 

【代码】

 

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 
 5 const int N = 5*1e5+10;
 6 
 7 char s[N];
 8 int root,last,sz,ch[N][26],fa[N],sum[N],val[N],l[N];
 9 void add(int x) {
10     int c=s[x]-a;
11     int p=last,np=++sz; last=np;
12     l[np]=x+1; val[np]=1;
13     for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
14     if(!p) fa[np]=root;
15     else {
16         int q=ch[p][c];
17         if(l[p]+1==l[q]) fa[np]=q;
18         else {
19             int nq=++sz; l[nq]=l[p]+1;
20             memcpy(ch[nq],ch[q],sizeof(ch[q]));
21             fa[nq]=fa[q];
22             fa[np]=fa[q]=nq;
23             for(;p&&q==ch[p][c];p=fa[p]) ch[p][c]=nq;
24         }
25     }
26 }
27 
28 int n,T,b[N],cnt[N];
29 
30 void get_sum() {
31     for(int i=1;i<=sz;i++) cnt[l[i]]++;
32     for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];
33     for(int i=sz;i>=1;i--) b[cnt[l[i]]--]=i;
34     for(int i=sz;i;i--)
35         if(!T) val[b[i]]=1;
36         else val[fa[b[i]]]+=val[b[i]];
37     val[1]=0;
38     for(int i=sz;i;i--) {
39         int p=b[i]; sum[p]=val[p];
40         for(int j=0;j<26;j++)
41             sum[p]+=sum[ch[p][j]];
42     }
43 }
44 
45 int main() {
46     scanf("%s",s);
47     n=strlen(s);
48     root=last=++sz;
49     for(int i=0;i<n;i++) add(i);
50     scanf("%d",&T);
51     int x,p=root; scanf("%d",&x);
52     get_sum();
53     if(x>sum[1]) { puts("-1");return 0; }
54     while(x>val[p]) {
55         for(int c=0;c<26;c++)if(ch[p][c]) {
56             if(sum[ch[p][c]]>=x) {
57                 putchar(a+c);
58                 x-=val[p]; p=ch[p][c];
59                 break;
60             }
61             else x-=sum[ch[p][c]];
62         }
63     }
64     return 0;
65 }

 

bzoj3998 [TJOI2015]弦论(SAM)

标签:

原文地址:http://www.cnblogs.com/lidaxin/p/5200675.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!