PAT 1005 后缀数组

   日期:2020-10-03     浏览:97    评论:0    
核心提示:#include <iostream>#include <unordered_map>#include <map>#include <cstring>using namespace std;struct SuffixArray{//后缀数组 #ifndef _SA_ #define maxn 1200000 #define maxcnt 270 #endif int n; //字符串长度 int sa[maxn]; //后
#include <iostream>
#include <cstring>
using namespace std;

struct SuffixArray{ //后缀数组 
	#ifndef _SA_
	#define maxn 1200000
	#define maxcnt 270 
	#endif
	int n;				//字符串长度 
	int sa[maxn];		//后缀数组, 排名为i的后缀的位置 
	int rk[maxn];		//名次数组,第i个位置开始的后缀排名 
	int ssa[maxn];		//保留后缀数组 
	int srk[maxn];		//保留名次数组 
	int cnt[maxn];	//计数数组 
	int height[maxn];	//排名相邻的两个后缀的最长公共前缀
	
	void doubling(string s, int m)//倍增法计算后缀数组 
	{ 
		//根据第一关键字进行基数排序 
		memset(cnt, 0, sizeof(cnt));
		for(int i=0; i<s.length(); ++i)	++cnt[ rk[i] = s[i] ];
		for(int i=1; i<m; ++i)			cnt[i] += cnt[i-1];
		for(int i=s.length()-1; i>=0; --i)	sa[ --cnt[s[i]] ] = i;
		for(int j=1, kk=1; kk < s.length(); j<<=1, m=kk)
		{ 
			//根据第二关键字进行基数排序,ssa为根据第二关键字排序后的后缀数组 
			int i;
			for(i=s.length()-j, kk=0; i < s.length(); ++i)		ssa[kk++] = i;
			for(i=0; i < s.length(); ++i)	if(sa[i] >= j)		ssa[kk++] = sa[i] - j;
			//根据第一关键字进行基数排序 
			for(i=0; i < s.length(); ++i)	srk[i] = rk[ssa[i]];
			memset(cnt, 0, sizeof(cnt));
			for(i=0; i<s.length(); ++i)		++cnt[ srk[i] ];
			for(i=1; i<m; ++i)				cnt[i] += cnt[i-1];
			for(i=s.length()-1; i>=0; --i)	sa[ --cnt[srk[i]] ] = ssa[i];
			memcpy(srk, rk, sizeof(rk));
			for( rk[sa[0]] = 0, kk = 1, i = 1; i < s.length(); ++i )
			{ 
				rk[sa[i]] = (srk[sa[i-1]] == srk[sa[i]] && sa[i-1] + j < s.length() && sa[i] + j < s.length() && srk[sa[i-1] + j] == srk[sa[i] + j] )?kk-1:kk++; 
			}
		}
	}
	
	void generateHeight(string s)//计算后缀最长公共前缀 
	{ 
		int i, j, kk = 0;
// for(i=0; i<s.length(); ++i) rk[sa[i]] = i;
		for(i=0; i<s.length(); height[rk[i++]] = kk)
		{ 
			if(rk[i])	for(kk?kk--:0, j = sa[rk[i]-1]; i+kk < s.length() && j+kk < s.length() && s[i+kk] == s[j+kk]; ++kk);
		}
			
	}
};
static SuffixArray sa;

int main()
{ 
	ios::sync_with_stdio(false);
	int N;
	string s;
	cin>>N;
	getline(cin, s);
	getline(cin, s);
	sa.doubling(s, 130);
	sa.generateHeight(s);
// for(int i=0; i<s.length(); ++i) cout<<sa.height[i]<<endl;//测试 
	int idx = sa.sa[0], ans = 0, maxL = 0;
	for(int i=1; i<s.length(); ++i)
	{ 
		if(sa.height[i]>=N)
		{ 
			ans++;
		}
		else
		{ 
			ans = 0;
		}
		if(ans > maxL && s.length()-sa.sa[i] >= N)
		{ 
			maxL = ans;
			idx = sa.sa[i];
		}
	}
	cout<<s.substr(idx, N)<<" "<<maxL+1<<endl;
	return 0;
}
	

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服