正题
考虑建出后缀自动机,在上面不断往后跑,每当trans一遍的时候,可以保证跳到的等价类一定包含s+c这个状态。
也就是说,其实通过什么途径到达当前的等价类其实并不重要。
所以就可以分情况,当t=0时,一个等价类的出现次数就是1,当t=1时,一个等价类的出现次数就是endpos集合的大小。
然后每一个节点统计一下自己可以到达的子串总数,就可以类似Trie树那样跑了。
这一题很刺激,因为很少有自己想出来而且一发过的。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
const int N=5e5+10;
char s[N];
struct sam{
int link,next[26],len;
}sam[N<<1];
struct edge{
int y,next;
}e[N<<1];
int first[N<<1];
int len=0,tot,last,type,k,t[N<<1],ansl,all[N<<1];
char ans[N];
bool vis[N<<1];
void insert(int c){
int now=++tot;sam[now].len=sam[last].len+1;t[now]=1;
while(last!=-1 && !sam[last].next[c]) sam[last].next[c]=now,last=sam[last].link;
if(last==-1) sam[now].link=0;
else{
int temp=sam[last].next[c];
if(sam[temp].len==sam[last].len+1) sam[now].link=temp;
else{
int np=++tot;sam[np]=sam[temp];sam[np].len=sam[last].len+1;
sam[temp].link=sam[now].link=np;
while(last!=-1 && sam[last].next[c]==temp) sam[last].next[c]=np,last=sam[last].link;
}
}
last=now;
}
void ins(int x,int y){
static int len=0;
e[++len]=(edge){y,first[x]};first[x]=len;
}
void dfs(int x){
for(int i=first[x];i!=0;i=e[i].next){
dfs(e[i].y);
t[x]+=t[e[i].y];
}
}
void get_all(int x){
if(vis[x]) return ;
vis[x]=true;all[x]=t[x];
for(int i=0;i<26;i++) if(sam[x].next[i]){
get_all(sam[x].next[i]);
all[x]+=all[sam[x].next[i]];
}
}
bool get_ans(int x){
if(t[x]>=k) {ans[++ansl]='\0';return true;}
k-=t[x];
for(int i=0;i<26;i++) if(sam[x].next[i]){
if(all[sam[x].next[i]]>=k) {
ans[++ansl]='a'+i;
return get_ans(sam[x].next[i]);
}
else k-=all[sam[x].next[i]];
}
return false;
}
int main(){
scanf("%s",s+1);len=strlen(s+1);
scanf("%d %d",&type,&k);
sam[last].link=-1;
for(int i=1;i<=len;i++) insert(s[i]-'a');
if(type==0) for(int i=1;i<=tot;i++) t[i]=1;
else{
for(int i=1;i<=tot;i++) ins(sam[i].link,i);
dfs(0);t[0]=0;
}
get_all(0);ansl=-1;
if(get_ans(0)) printf("%s",ans);
else printf("-1");
}
本文探讨了如何利用后缀自动机解决复杂的字符串匹配问题,详细介绍了后缀自动机的构建过程,以及如何在自动机上进行有效的字符串搜索。文章通过一个具体的实例,展示了如何统计字符串中特定子串的出现次数,并提出了一种新颖的方法来解决这一问题。通过递归遍历和动态规划,该方法能够高效地找到所有可能的子串并计数。
368

被折叠的 条评论
为什么被折叠?



