bzoj 4319 cerc2008 Suffix reconstruction——贪心构造
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4319
如果字符集有 5e5 那么大的话,挨个填上去就行了。但只有26个字符,所以要贪心地尽量填和上一次一样的字符。
按 sa[ ] 的顺序从小到大填字符,判断这个位置 x 能否填上一次在 y 填的字符的条件就是 rk[ x+1 ] > rk[ y+1 ]。
因为 x 的字典序比 y 大,而 x 位置要填和 y 一样的字符,所以 x 的后面应该比 y 大。发现后面部分也是两个后缀,所以利用“接下来会使它们合法”这一限制,就能判断 x 位置填什么了。
自己的思路有待锻炼!要尝试归纳限制条件!
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=5e5+5; int n,sa[N],rk[N]; char a[N]; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar(); return fx?ret:-ret; } int main() { n=rdn();for(int i=1;i<=n;i++)sa[i]=rdn(),rk[sa[i]]=i; int i,p=0;a[sa[1]]=0; for(i=2;i<=n;i++) { if(rk[sa[i]+1]>rk[sa[i-1]+1])a[sa[i]]=p; else {a[sa[i]]=++p;if(p==26)break;} } if(i<=n)puts("-1"); else {for(int i=1;i<=n;i++)putchar(a[i]+'a');puts("");} return 0; }