【洛谷 P3809】 【后缀数组】【模板】后缀排序

【洛谷 P3809】 【后缀数组】【模板】后缀排序

标题

在这里插入图片描述


解题思路

嗯。。。这是道模板题
雾里看花状态,咱就给点注释吧
我看的是这篇题解


代码

#include<iostream>
#include<cstdio>
using namespace std;
string s;
int n,m=1000;
int z[1001000],w[1000100],c[1000100],sa[1001000],wa[1000100],wb[1000100];
bool cmp(int *r,int xx,int yy,int k)
{
	 return (r[xx]==r[yy]&&r[xx+k]==r[yy+k]);
}
void work()
{
	 int j=1,p,d,*x=wa,*y=wb;
	 for (int i=0;i<n;i++) z[x[i]=c[i]]++;
	 for (int i=1;i<m;i++) z[i]+=z[i-1];
	 for (int i=n-1;i>=0;i--) sa[--z[x[i]]]=i;  //单个字母排一次
	 while(1) 
	 {
	 	 p=0,d=1;
	 	 for (int i=n-j;i<n;i++) y[p++]=i;  //没有第二关键字放在最前面
		 for (int i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j;   //位置大于j的才有第二关键字
		 for (int i=0;i<m;i++) z[i]=0;
		 for (int i=0;i<n;i++) w[i]=x[y[i]],z[w[i]]++;  //取相应的第一关键字,然后排序
		 for (int i=1;i<m;i++) z[i]+=z[i-1]; 
		 for (int i=n-1;i>=0;i--) sa[--z[w[i]]]=y[i];  //取排名
		 swap(x,y);
		 x[sa[0]]=0;
		 for (int i=1;i<n;i++)   //如果相同取一样的排名
		     if (cmp(y,sa[i-1],sa[i],j))
		        x[sa[i]]=d-1;
		        else x[sa[i]]=d++;
		 m=d; 
		 if (d==n) 
		 {
		 	for (int i=0;i<n;i++)
		 	    printf("%d ",sa[i]+1);
		 	return;
		 } 
		 j*=2;  //倍增
	 }
}
int main()
{
    cin>>s;
    n=s.size();
    for (int i=0;i<n;i++)
        c[i]=s[i]-'0'+1;
    work();
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值