【构造】后缀数组求逆

来源:互联网 发布:java log4j 用法 编辑:程序博客网 时间:2024/04/30 23:04

根据sa[]数组反求原数组,只能26小写字母。

有了sa[],自然有了rank[],从原数组最后的往前考虑,我们尽量要将原数组用小的字符集表示,因为只有26个字母可以表示,那么排名比当前枚举的小一位的的字符串,如果第二位比其小的话,那么排名比当前枚举的小一位的的字符串的首位可与其首位相同,同样的向比它大的考虑一遍则可使字符集尽量小。

#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>const int oo=1073741819;int n,i,a[500005],rk[500006],sa[500006],min,s;char ch[500005];void init(){  int i,k;  scanf("%d\n",&n);  for (i=1;i<=n;i++) scanf("%d",&sa[i]),rk[sa[i]]=i;  k=rk[n],a[n]=0;  for (i=k;i>=2;i--)     if (rk[sa[i-1]+1]<rk[sa[i]+1]) a[sa[i-1]]=a[sa[i]];else a[sa[i-1]]=a[sa[i]]-1;  for (i=k;i<=n-1;i++)     if (rk[sa[i+1]+1]>rk[sa[i]+1]) a[sa[i+1]]=a[sa[i]];else a[sa[i+1]]=a[sa[i]]+1;  min=oo;  for (i=1;i<=n;i++)    if (a[i]<min) min=a[i];  for (i=1;i<=n;i++) printf("%c",a[i]-min+97);}int main(){  freopen("input.txt","r",stdin);  freopen("output.txt","w",stdout);    init();  return 0;}


原创粉丝点击