POJ1509 Glass Beads [后缀自动机]
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                POJ1509 Glass Beads [后缀自动机]
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                題意:
給一個字符串S,每次可以將它的第一個字符移到最后面,求這樣能得到的字典序最小的字符串。輸出開始下標
?
練習SAM第一題!
SS構造SAM,然后從開始盡量走最小走n步就可以啦
什么?開始位置?!Right集合中最左的位置-len
直接t[u].val-n+1,為什么啊沒有一個人的題解解釋嗚嗚嗚嗚嗚嗚
想了想,這個最小串Right等價類的最長串一定到了開頭位置,卡不掉吧,最小串唯一一定成立,如果不唯一好像只可能是自己吧
?
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=2e4+5; int n; char s[N]; struct State{int ch[26],par,val;State():par(0),val(0){memset(ch,0,sizeof(ch));} }t[N<<1]; int sz,root,last; inline int nw(int _){t[++sz].val=_;return sz;} void iniSAM(){sz=0;root=last=nw(0);} void extend(int c){int p=last,np=nw(t[p].val+1);while(p&&t[p].ch[c]==0) t[p].ch[c]=np,p=t[p].par;if(p==0) t[np].par=root;else{int q=t[p].ch[c];if(t[q].val==t[p].val+1) t[np].par=q;else{int nq=nw(t[p].val+1);memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch));t[nq].par=t[q].par;t[q].par=t[np].par=nq;while(p&&t[p].ch[c]==q) t[p].ch[c]=nq,p=t[p].par;}}last=np; } void solve(){iniSAM();memset(t,0,sizeof(t));for(int i=1;i<=n;i++) extend(s[i]-'a');for(int i=1;i<=n;i++) extend(s[i]-'a');int u=root;for(int i=1;i<=n;i++)for(int k=0;k<26;k++) if(t[u].ch[k]) {u=t[u].ch[k];break;}printf("%d\n",t[u].val-n+1); } int main(){freopen("in","r",stdin);int T;scanf("%d",&T);while(T--){scanf("%s",s+1);n=strlen(s+1);solve();} }?
總結
以上是生活随笔為你收集整理的POJ1509 Glass Beads [后缀自动机]的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: nyoj 寻找最大数
- 下一篇: CSS------如何让大小不一样的di
