码迷,mamicode.com
首页 > 其他好文 > 详细

后缀数组模板

时间:2014-07-16 12:39:50      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:blog   os   art   for   io   div   

#pragma warning (disable:4996)
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <cassert>
using namespace std;

#define ll long long
#define maxn 100000


struct SuffixArray
{
	int n;
	int m[2][maxn];
	int sa[maxn];
	char s[maxn];

	void indexSort(int sa[], int ord[], int id[], int nId){
		static int cnt[maxn];
		memset(cnt, 0, sizeof(0)*nId);
		for (int i = 0; i < n; i++){
			cnt[id[i]]++;
		}
		partial_sum(cnt, cnt + nId, cnt);
		for (int i = n - 1; i >= 0; i--){
			sa[--cnt[id[ord[i]]]] = ord[i];
		}
	}

	int *id, *oId;

	void init(){
		n = strlen(s) + 1;
		static int w[maxn];
		for (int i = 0; i <= n; i++) w[i] = s[i];
		sort(w, w + n);
		int nId = unique(w, w + n) - w;
		id = m[0], oId = m[1];
		for (int i = 0; i < n; i++){
			id[i] = lower_bound(w, w + nId, s[i]) - w;
		}
		static int ord[maxn];
		for (int i = 0; i < n; i++){
			ord[i] = i;
		}
		indexSort(sa, ord, id, nId);
		for (int k = 1; k <= n&&nId < n; k <<= 1){
			int cur = 0;
			for (int i = n - k; i < n; i++){
				ord[cur++] = i;
			}
			for (int i = 0; i < n; i++){
				if (sa[i] >= k) ord[cur++] = sa[i] - k;
			}
			indexSort(sa, ord, id, nId);
			cur = 0;
			swap(oId, id);
			for (int i = 0; i < n; i++){
				int c = sa[i], p = i ? sa[i - 1] : 0;
				id[c] = (i == 0 || oId[c] != oId[p] || oId[c + k] != oId[p + k]) ? cur++ : cur - 1;
			}
			nId = cur;
		}
	}

	// lcp relevant
	int rk[maxn], lcp[maxn];
	void getlcp(){
		for (int i = 0; i < n; i++) rk[sa[i]] = i;
		int h = 0;
		lcp[0] = 0;
		for (int i = 0; i < n; i++){
			int j = sa[rk[i] - 1];
			for (h ? h-- : 0; i + h < n&&j + h < n&&s[i + h] == s[j + h]; h++);
			lcp[rk[i] - 1] = h;
		}
	}

	// lcp query relevant
	int d[maxn + 50][25];

	void getrmq(){
		for (int i = 0; i < n; i++) d[i][0] = lcp[i];
		for (int j = 1; (1 << j) < n; j++){
			for (int i = 0; (i + (1 << j) - 1) < n; i++){
				d[i][j] = min(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]);
			}
		}
	}

	int rmq_query(int l, int r){
		if (l > r) swap(l, r); r -= 1;
		int k = 0; int len = r - l + 1;
		while ((1 << (k + 1)) < len) k++;
		return min(d[l][k], d[r - (1 << k) + 1][k]);
	}

	int rmq_query2(int l, int r){
		l = rk[l], r = rk[r];
		if (l > r) swap(l, r); r -= 1;
		int k = 0; int len = r - l + 1;
		while ((1 << (k + 1)) < len) k++;
		return min(d[l][k], d[r - (1 << k) + 1][k]);
	}
}sa;

int main()
{
	while (scanf("%s", sa.s)){
		sa.init();
		sa.getlcp();
		sa.getrmq();
		cout << sa.rmq_query2(0,7) << endl;
		cout << sa.rmq_query2(4, 7) << endl;
	}
}

后缀数组模板,布布扣,bubuko.com

后缀数组模板

标签:blog   os   art   for   io   div   

原文地址:http://www.cnblogs.com/chanme/p/3848322.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!