當字符集足夠大的時候一定可以構造出來,這個時候考慮$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 }