[KMP]BZOJ 4974 [Lydsy1708月賽]字串大師 題解
阿新 • • 發佈:2018-12-16
題目大意
給出一個長度為n的字串,求這個字串的所有字首的最小迴圈節,現在反過來,給出所有字首的最小迴圈節,求字典序最小的字串。
解題分析
最小迴圈節=i-nxt[i]
那麼可以求出nxt陣列。
求出來了又如何?
如果Nxt[i]已知,注意nxt[i]的定義是s[1…nxt[i]]=s[i-nxt[i]+1…n],那麼明顯s[i]=s[nxt[i]]
但如果nxt[i]=0,那怎麼辦?
注意到字串只由小寫字母構成,也就是最多26個元素,那麼可以1個1個試試看,代入用前面的nxt陣列驗證。
然後好了。
示例程式碼
#include<cstdio> #include<cstring> using namespace std; int n,tot,nxt[100005]; char s[100005]; int main() { freopen("string.in","r",stdin); freopen("string.out","w",stdout); scanf("%d",&n); for (int i=1,x;i<=n;i++){ scanf("%d",&x); nxt[i]=i-x; if (i==1) {s[1]='a'; continue;} if (nxt[i]) s[i]=s[nxt[i]]; else{ for (int z=0,j;z<26;z++){ s[i]='a'+z; j=nxt[i-1]; while (j&&s[j+1]!=s[i]) j=nxt[j]; if (s[j+1]!=s[i]&&!j) break; } } } for (int i=1;i<=n;i++) putchar(s[i]); return 0; }