poj1509 Glass Beads SAM

来源:互联网 发布:深入理解java内存模型 编辑:程序博客网 时间:2024/05/16 10:20

    最近打算把SAM捡回来,找个水题先练练手...这题是给一个字符串,首尾相连成环,求一个位置,使得从这个位置开始走一圈得到的串字典序最小。方法很多,后缀自动机也能做,把原串复制两边,一次插入到自动机中,然后从根节点开始,从小打到走len步,当前的位置就是最小字典序的串的位置了..

#include <iostream>#include <cstdio>#include <algorithm>#include <memory.h>#include <queue>#include <cstring>#include <cmath>using namespace std;typedef long long ll;const int maxn=20100;const int S=26;int tot,len;int n,m;int wtop[maxn<<1];int c[maxn<<1];int k,ans;struct node{    node *pre,*go[S];    int val,id;}*tail,*root,que[maxn<<1],top[maxn<<1];char str[maxn],s[maxn],ss[maxn];inline int idx(char c){    return c-'a';}struct SAM{    void init()    {        memset(que,0,sizeof que);        tot=0;        len=1;        root=tail=&que[tot++];        root->id=0;        root->val=0;    }    void add(int c,int l)    {        node* p=tail;        node* np=&que[tot++];        np->val=l;        np->id=tot-1;        while(p && p->go[c]==NULL) p->go[c]=np,p=p->pre;        if (p==NULL) np->pre=root;        else        {            node* q=p->go[c];            if (p->val+1==q->val) np->pre=q;            else            {                node *nq=&que[tot++];                *nq=*q;                nq->id=tot-1;                nq->val=p->val+1;                np->pre=q->pre=nq;                while(p && p->go[c]==q) p->go[c]=nq,p=p->pre;            }        }        tail=np;    }    void debug_suff()    {        for (int i=0; i<tot; i++)        {            for (int c=0; c<S; c++)            if (que[i].go[c])            {                cout<<que[i].id<<" "<<que[i].go[c]->id<<endl;            }        }    }    void debug_pre()    {        for (int i=1; i<tot; i++)        cout<<que[i].id<<" "<<que[i].pre->id<<endl;    }}sam;int main(){//    freopen("in.txt","r",stdin);    int tt;    scanf("%d",&tt);    while(tt--)    {        scanf("%s",s);        sam.init();        int l=strlen(s);        for (int i=0; i<l; i++)        sam.add(idx(s[i]),len++);        for (int i=0; i<l; i++)        sam.add(idx(s[i]),len++);//        sam.debug_suff();//        puts("-----------------------------");//        sam.debug_pre();        node* rt=root;        for (int i=0; i<l; i++)            for (int c=0; c<S; c++)            {                if (rt->go[c])                {                    rt=rt->go[c];                    break;                }            }        printf("%d\n",rt->val-l+1);    }    return 0;}


0 0
原创粉丝点击