bzoj1031

把原字符串直接接一个一样的在后面,这样就能解决环的问题了,直接后缀数组sa水过。

注意dsort的范围,不知为何,第一次设400然后RE。

看来是有特殊字符的!?

#include<cstdio>
#include<cstdlib>
#include<cstring>
int sa[200005];
int rank[200005];
char s[200005];
int dsort[200005],Y[200005],wr[200005];
bool same(int a,int b,int l)
{
    return wr[a]==wr[b]&&wr[a+l]==wr[b+l];
}
void make_sa(int n,int m)
{
 for (int i=0;i<=m;i++)dsort[i]=0;
 for (int i=1;i<=n;i++)dsort[rank[i]]++;
 for (int i=1;i<=m;i++)dsort[i]+=dsort[i-1];
 for (int i=n;i>=1;i--)sa[dsort[rank[i]]--]=i;
 int ln=1,p=0;
 while(p<n)
 {
  int cnt=0;
  for (int i=n-ln+1;i<=n;i++)Y[++cnt]=i;
  for (int i=1;i<=n;i++)if (sa[i]>ln)Y[++cnt]=sa[i]-ln;
   
  for (int i=1;i<=n;i++)wr[i]=rank[Y[i]];
  for (int i=0;i<=m;i++)dsort[i]=0;
  for (int i=1;i<=n;i++)dsort[wr[i]]++;
  for (int i=1;i<=m;i++)dsort[i]+=dsort[i-1];
  for (int i=n;i>=1;i--)sa[dsort[wr[i]]--]=Y[i];
   
  memcpy(wr,rank,sizeof(wr));
  rank[sa[1]]=1;p=1;
  for (int i=2;i<=n;i++)
  {
   if (!same(sa[i],sa[i-1],ln))p++;
   rank[sa[i]]=p;   
  }
  m=p;ln*=2;
 }
}
int main()
{
    scanf("%s",s);
    int soy=strlen(s);
    sprintf(s,"%s%s",s,s);
    int l=strlen(s);
    for (int i=1;i<=l;i++)
    rank[i]=s[i-1];
    make_sa(l,800);
    /*for (int i=1;i<=l;i++)
    printf("i:%d sa:%d\n",i,sa[i]);
    printf("%d\n",soy);*/
    for (int i=1;i<=l;i++)
    {
     if (sa[i]>soy)continue;
     printf("%c",s[sa[i]+soy-2]);   
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值