Rank
11.3
对于后缀排名最小的那个位置, 不妨令它为’a’. 本着让使用的字母尽可能少的原则, 对于两个排名相邻的位置i, j, 设rank[i] < rank[j], 那么如果rank[i+1] < rank[j+1]那么i和j位置上的字符就能够相同, 否则不能. 那么从排名为1的往后推就可以了, 至于字典序最小并没有什么用.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#define LL long long
#define N 200010
using namespace std;
int n;
char ans[N];
int isnot[N];
int sa[N], rank[N];
int main(){
freopen ("rank.in", "r", stdin);
freopen ("rank.out", "w", stdout);
scanf("%d", &n);
for(int i=1; i<=n; ++i) scanf("%d", &rank[i]) ;
for(int i=1; i<=n; ++i) sa[rank[i]] = i;
for(int i=1; i<n; ++i)
if( rank[sa[i]+1] > rank[sa[i+1]+1] ){//相邻排名的串,去掉首位后的rank比较
isnot[sa[i+1]] = 1;//两个首字母不同
}
char cur = 'a';
ans[sa[1]] = cur;
for(int i=2; i<=n; ++i){
if( isnot[sa[i]] ){
++cur;
if(cur > 'z'){
puts("-1"); return 0;
}
}
ans[sa[i]] = cur;
}
puts(ans + 1) ;
}