poj 2774 后缀数组(模板题)

点击打开链接

模板

#include 
#include 
#include 
#include 
using namespace std;
const int M =1e6+20;
int len,len1,len2;
char s[M];
int sa[M];//sa[i]排名i的后缀编号 

int c[M];//计数数组 c[i]=j表示关键字<=i的有j个  
int t1[M],t2[M]; 
void SA(char *s,int n,int m)	//n为strlen(s)+1; m为最大字符的ascii码值
{

	int *x=t1;//x[i]=j表示后缀i的排名 (每一轮的rank) 
	
	int *y=t2;//y[p]=i;后缀i的第二关键字排名为p 
	
	int i;
	for(i=0;i=0;i--)//长度(1)的名次数组 
	sa[--c[x[i]]]=i;//aabaaaab 若x[i]值相同的sa靠前的小 
	
	for(int k=1;k<=n;k<<=1)
	{
		int p=0;
		for(i=n-k;i=k)//只有编号大于k的才能作为第二关键字 
			{
				y[p++]=sa[i]-k;
			}
		}
		//通过x[],y[]计算每个后缀的长为2*k前缀的sa数组
		for(i=0;i=0;i--)
		sa[--c[x[y[i]]]]=y[i];//后缀y[i]在它的2*k长度中排名为? 
		//后缀y[i]的第一关键字排名为c[x[y[i]]] 第一关键字相同时 此时看第二关键字
		//y[i]中i越小 第二关键字排名就越小 后缀y[i]排名就越小 (逆推的原因)
	
		//接着更新x为长度2*k的名次数字 
		swap(x,y);//令y表示名次数组(rank)
		p=1;//此时p记录排名的不同的个数
		x[sa[0]]=0;
		for(i=1;i=n) break;//字典序比较法得出 当前排名都不同时,最终排名就为此排名 
		m=p; //
	} 
}
int rank[M],height[M];//设 height[i]=LCP(Suffix(sa[i]),Suffix(sa[i-1]))后缀排名为i和i-1的LCP 
//则 h[i]=height[rank[i]]= 后缀i和它前一个后缀的 LCP
//h[i]>=h[i-1]-1
//h[i-1]为后缀i-1和它排在它前一个的后缀k的LCP
//同时去掉相同的首字符之后 后缀k+1和和后缀i的LCP为h[i]=h[i-1]-1 
//因为后缀k+1和后缀i名次不一定相邻 所以若存在后缀t为后缀i相邻 则h[i]>=h[i]-1; 
void Height()
{
	int i,j,k=0;
	for(i=0;i=h[i-1]-1;先减一
		int j=sa[rank[i]-1];//前一个后缀 
		while(s[i+k]==s[j+k])
		k++;
		
		height[rank[i]]=k;
			
	}	
} 
void solve()
{
	int ans=0;
	for(int i=2;ians)
		{
			//后缀sa[i]和sa[i-1]不能在同一个串中 
			if(sa[i-1]>=0&&sa[i-1]len1&&sa[i]=0&&sa[i]len1&&sa[i-1]



你可能感兴趣的:(Data,Structure)