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;
}

 

posted on 2018-12-06 21:42  Narh  阅读(178)  评论(0编辑  收藏  举报

导航