uva 719 Glass Beads (后缀自动机)

来源:互联网 发布:淘宝上怎么开企业店铺 编辑:程序博客网 时间:2024/06/05 10:37

题意:

给出一个串,如bcdaf长度n=5,可以将串头尾相连,在这个循环串中求字典序最小且长度为n的串的开头点位置。

题解:

后缀自动机中遍历dfs找到第n个点对应的肯定是长度为n字典序最小的子串,并且结尾点就是遍历的结尾点。


#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))typedef long long ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const int MOD=10007;const int maxn=10050;const int maxm=200005;const int SIZE=maxn<<2;const int type=26;char str[maxn<<1];int n;struct SuffixAutoMaton{    int next[SIZE][type],fa[SIZE],len[SIZE],num[SIZE];    int tol,last;    int newNode(int x){        len[tol]=x;        fa[tol]=-1;        num[tol]=0;        for(int i=0;i<type;i++)            next[tol][i]=-1;        return tol++;    }    void Init(){        tol=0;        last=newNode(0);    }    void add(int k){        int now=last;        int end=newNode(len[now]+1);        while(now!=-1&&next[now][k]==-1){            next[now][k]=end;            now=fa[now];        }        if(now==-1) fa[end]=0;        else{            int nxt=next[now][k];            if(len[nxt]==len[now]+1) fa[end]=nxt;            else{                int cnxt=newNode(len[now]+1);                for(int i=0;i<type;i++)next[cnxt][i]=next[nxt][i];                fa[cnxt]=fa[nxt];                fa[nxt]=fa[end]=cnxt;                while(now!=-1&&next[now][k]==nxt){                    next[now][k]=cnxt;                    now=fa[now];                }            }        }        last=end;    }    void Insert(char T[]){        for(int i=0;T[i];i++){            add(T[i]-'a');        }    }    int dfs(int u,int step){        if(step==n)return len[u];        for(int i=0;i<type;i++){            if(next[u][i]!=-1){                int k=dfs(next[u][i],step+1);                if(k)return k;            }        }        return 0;    }    void solve(){        printf("%d\n",dfs(0,0)-n+1);    }}sam;int main(){    int T,L;    scanf("%d",&T);    while(T--){        scanf("%s",str);        L=n=strlen(str);        for(int i=0;i<n;i++)str[L++]=str[i];        str[L]='\0';        sam.Init();        sam.Insert(str);        sam.solve();    }    return 0;}/***/




0 0
原创粉丝点击