UOJ #35 后缀排序(后缀数组)

题目链接


题解:后缀数组板子

之前学后缀数组只是学了个大概,而且写的是二维的。现在从头理一遍,改成了算法导论上的写法。。

#include
#include
#include
#include
#define N 100003
using namespace std;
int rank[N],sa[N],xx[N],yy[N],*x,*y,height[N],b[N],a[N],p,len;
char s[N];
int cmp(int i,int j,int l)
{
	return y[i]==y[j]&&(i+l>=len?-1:y[i+l])==(j+l>=len?-1:y[j+l]);
}
void get_SA()
{
	x=xx; y=yy; int m=26;
	for (int i=0;i=0;i--) sa[--b[x[i]]]=i;
	for (int k=1;k<=len;k<<=1) {//进行基数排序,基数排序需要进行两次排序,第一次是以第二关键字排序,第二次是以第一关键字排序,我们在进行排序的时候对于每个位置来说第一关键
	//就是当前位置为起点长度2^(k-1)的串的排名,第二关键字就是x+2^(k-1)位置开始长度为2^(k-1)的串的排名。 
		p=-1;
		for (int i=len-k;i=k) y[++p]=sa[i]-k; //由上一次的sa直接计算出第二关键字,i是从小到大有序的,那么sa[i]的排名会是sa[i]-k的第二关键字,那么这样得到的就是第二关键字的位置排名。 
		for (int i=0;i<=m;i++) b[i]=0;
		for (int i=0;i=0;i--) sa[--b[x[y[i]]]]=y[i];//对于第一关键字进行排序 
		swap(x,y); p=1; x[sa[0]]=0;
		for (int i=1;i=len) break;
		m=p;
	}
	p=0;
	for (int i=0;i


你可能感兴趣的:(后缀数组)