BZOJ4947 字串大師 KMP

2022-02-06 04:26:38 字數 1413 閱讀 2779

time limit: 1 sec  memory limit: 256 mb

submit: 739  solved: 358

[submit][status][discuss]

乙個串t是s的迴圈節,當且僅當存在正整數k,使得s是t^k(即t重複k次)的字首,比如abcd是abcdabcdab的迴圈節

。給定乙個長度為n的僅由小寫字元構成的字串s,請對於每個k(1<=k<=n),求出s長度為k的字首的最短迴圈節的

長度per_i。字串大師小q覺得這個問題過於簡單,於是花了一分鐘將其ac了,他想檢驗你是否也是字串大師。

小q告訴你n以及per_1,per_2,...,per_n,請找到乙個長度為n的小寫字串s,使得s能對應上per。

第一行包含乙個正整數n(1<=n<=100000),表示字串的長度。

第二行包含n個正整數per_1,per_2,...per_n(1<=per_i<=i),表示每個字首的最短迴圈節長度。

輸入資料保證至少存在一組可行解。

輸出一行乙個長度為n的小寫字串s,即某個滿足條件的s。

若有多個可行的s,輸出字典序最小的那乙個。

51 2 2 2 5

ababb

[submit][status][discuss]

題解:

我們由最短迴圈節=i-nxt[i],可以求出每個nxt。

然後貪心地求出答案。

每一位如果它nxt不為0,直接ans[i]=ans[xt[i]];

如果它等於0,

那麼考慮kmp的過程,沿著nxt[i-1]一直往前跑找到的每乙個j,ans[j+1]都不能是現在的ans[i],然後每次取未出現過的字典序最小的字母即可;

code:

1 #include 2 #include 3 #include 4

using

namespace

std;56

intn;

7int nxt[100010];8

char ans[100010];9

10int

main()

1119 nxt[0] = -1

;20 ans[1] = 'a'

;2122for (register int i = 2 ; i <= n ; i ++)

2335

for (register int j = '

a' ; j <= '

z' ; j ++)

3638}39

}40}41

for (register int i = 1 ; i <= n ; i ++) printf("%c"

, ans[i]);

42return0;

43 }

BZOJ4974 字串大師

不難發現結論pe ri i nex ti,nex t 就是kmp裡的失配陣列。考慮構造乙個字串 s 滿足上述ne xt陣列,定義 i 的失配集為 n exti 1 1 的失配集。若ne xti 0 則si sne xti 若ne xti 0 則 i 必須和其失配集中的字元互不相同,因為字典序要最小,...

KMP 字串 BZOJ4974字串大師

在kmp演算法中,fai lfail fail 指標有乙個特殊的性質,i f aili i fail i i fail i 是前i個字元的最小迴圈節大小。所以這題相當於就是說,給了你每個點的fail指標,求乙個滿足的字串。那麼按照建fail指標的方式倒過來做就好了 include include i...

4974 字串大師

description 乙個串t是s的迴圈節,當且僅當存在正整數k,使得s是t k 即t重複k次 的字首,比如abcd是abcdabcdab的迴圈節 給定乙個長度為n的僅由小寫字元構成的字串s,請對於每個k 1 k n 求出s長度為k的字首的最短迴圈節的 長度per i。字串大師小q覺得這個問題過於...