【模板】后缀数组

[模板] 后缀数组

int rak[maxn],height[maxn];

void cal_height(vector<int> p,string s){
	int n = s.length();
	int k = 0;
	for(int i = 0;i < n;i++)
		rak[p[i]] = i;
	for(int i = 0;i < n;i++){
		if(k) k--;
		int j = p[rak[i] - 1];
		while(i + k < n &&  j + k < n && s[i + k] == s[j + k]) k++;
		height[rak[i]] = k;
	}	
	for(int i = 0;i < n;i++)
		cout << height[i] << '
';
}


void count_sort(vector<int> &p,vector<int> &c){
	int n = p.size();
	vector<int> cnt(n);
	for(auto x:c)
		cnt[x]++;
	vector<int> p_new(n);
	vector<int> pos(n);
	pos[0] = 0;
	for(int i = 1;i < n;i++)
		pos[i] = pos[i - 1] + cnt[i - 1];
	for(auto x:p){
		int i = c[x];
		p_new[pos[i]] = x;
		pos[i]++;
	}
	p = p_new; 
}

void SA(string s){
	s.pb('$');
	int n = s.length();
	vector<int> p(n),c(n);
	{
		vector<pair<char,int>> a(n);
		for(int i = 0;i < n;i++) 
			a[i] = make_pair(s[i],i);
		sort(a.begin(),a.end());
		for(int i = 0;i < n;i++) 
			p[i] = a[i].se;
		c[p[0]] = 0;
		for(int i = 1;i < n ;i++){
			if(a[i].fi == a[i - 1].fi)
				c[p[i]] = c[p[i - 1]];
			else
				c[p[i]] = c[p[i - 1]] + 1;
		}
	}
	int k = 0;
	while((1 << k) < n){
		for(int i = 0;i < n;i++)
			p[i] = (p[i] - (1 << k) + n) % n;
		count_sort(p,c);
		vector<int> c_new(n);
		c_new[p[0]] = 0;
		for(int i = 1;i < n;i++){
			pii pre = make_pair(c[p[i - 1]],c[(p[i - 1] + (1 << k)) % n]);
			pii now = make_pair(c[p[i]],c[(p[i] + (1 << k)) % n]);
			if(now == pre)
				c_new[p[i]] = c_new[p[i - 1]];
			else
				c_new[p[i]] = c_new[p[i - 1]] + 1;
		}
		c = c_new;
		k++;
	}
	cal_height(p,s);
}



int main(){
	string s;
	cin >> s;
	SA(s);
}
原文地址:https://www.cnblogs.com/hznumqf/p/14038002.html