bzoj 4319 [Cerc 2008] Suffix reconstruction - 構造

題目傳送門

  傳送門

題目大意

  給定一個字符串的sa數組,要求輸出任意一個由小寫字母組成的合法字符串,不存在輸出-1.

  當字符集足夠大的時候一定可以構造出來,這個時候考慮$s_{sa_i} = i$。

  考慮按照$sa_i$的順序來填字符。根據$sa$,我們可以計算出$rk$。

  顯然$0 \leqslant s_{sa_i} - s_{sa_{i - 1}}\leqslant 1$(如果小於0,那麼不合法,如果大於1,那麼可以改小)。

  現在考慮$sa_i$和$sa_{i - 1}$指的兩個後綴,可以用$rk$比較它們去掉首字母后的兩個串的大小。然後就能判斷這一位填的字符與前一位是相等還是恰好大1。

Code

 1 /**
 2  * bzoj
 3  * Problem#4319
 4  * Accepted
 5  * Time: 684ms
 6  * Memory: 5684k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 typedef bool boolean;
11 
12 const int N = 5e5 + 5;
13 
14 int n;
15 char str[N];
16 int sa[N], rk[N];
17 
18 int main() {
19     scanf("%d", &n);
20     rk[n + 1] = 0;
21     for (int i = 1; i <= n; i++) {
22         scanf("%d", sa + i);
23         rk[sa[i]] = i;
24     } 
25     int cnt = 0;
26     str[sa[1]] = 'a';
27     for (int i = 2; i <= n; i++) {
28         if (rk[sa[i] + 1] < rk[sa[i - 1] + 1])
29             cnt++;
30         str[sa[i]] = 'a' + cnt;
31     }
32     if (cnt >= 26) {
33         puts("-1");
34     } else {
35         puts(str + 1);
36     }
37     return 0;
38 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章