[POJ1509]Glass Beads && 後綴自動機

(right集合只包含大於等於v的值 所以val裏面存的其實是right集合的最小值)

模板題啊.... 我也不知道爲什麼UVA那個要開三倍空間才能過 如果有人知道的話求解釋啊

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#define SF scanf
#define PF printf
#define idx(c) (c-'a')
using namespace std;
typedef long long LL;
const int MAXN = 10000;
int n;
struct SAM {
	int ncnt, last;
	int fa[MAXN*2+10], ch[MAXN*2+10][26], step[MAXN*2+10];
	int val[MAXN*2+10];
	SAM () { last = ++ncnt; }
	void extend(int c, int v) {
		int p = last, np = last = ++ncnt;
		step[np] = step[p]+1; val[np] = v;
		while(!ch[p][c] && p) ch[p][c] = np, p = fa[p];
		if(!p) fa[np] = 1;
		else {
			int q = ch[p][c], nq;
			if(step[p]+1 == step[q]) fa[np] = q;
			else {
				nq = ++ncnt;
				step[nq] = step[p]+1; val[nq] = val[q];
				memcpy(ch[nq], ch[q], sizeof(ch[p]));
				fa[nq] = fa[q];
				fa[np] = fa[q] = nq;
				while(ch[p][c] == q) ch[p][c] = nq, p = fa[p];
			}
		}
	}
	void init() {
		last = ncnt = 1;
		memset(ch[1], 0, sizeof(ch));
	}
	void build(char *s) {
		init();
		int len = strlen(s);
		for(int i = 0; i < len; i++)
			extend(idx(s[i]), i+1);
	}
} sam;
char s[MAXN*2+10];
int main() {
	int _T; SF("%d", &_T); while(_T--) {
		SF("%s", s);
		n = strlen(s);
		for(int i = 0; i < n; i++) s[i+n] = s[i];
		s[n<<1] = 0;
		sam.build(s);
		int cur = 1;
		for(int i = 0; i < n; i++) 
			for(int j = 0; j < 26; j++)
				if(sam.ch[cur][j]) {
					cur = sam.ch[cur][j];
					break;
				}
		PF("%d\n", sam.val[cur]-n+1);
	}
}


發佈了192 篇原創文章 · 獲贊 13 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章