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

POJ 1509 Glass Beads 后缀自动机

时间:2015-01-17 10:04:22      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:poj   后缀自动机   后缀树   

题目大意:给出一个环形的字符串,问从哪里开始是的这个字符串的字典序最小。


思路:最小表示法和后缀自动机的裸题,不过我是为了学后缀自动机才写的这个题,就没有去学最小表示法。

做法很简单,先建立一个后缀自动机,然后从根开始沿tranc指针从a->z走len次到达的点就是字典序最小的字符串的结尾点,求起始点只要减一下长度再+1即可。


对于后缀自动机的理解:http://wyfcyx.is-programmer.com/posts/76107.html


CODE:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 10010
using namespace std;

struct Complex{
	Complex *tranc[26],*father;
	short len;
}mempool[MAX << 2],*C = mempool,none,*nil = &none,*root,*last;
Complex *NewComplex(int _)
{
	C->len = _;
	fill(C->tranc,C->tranc + 26,nil);
	C->father = nil;
	return C++;
}

int T;
char s[MAX];

inline void Initialize()
{
	C = mempool;
	root = last = NewComplex(0);
}

inline void Add(int c)
{
	Complex *np = NewComplex(last->len + 1),*p = last;
	for(; p != nil && p->tranc[c] == nil; p = p->father)
		p->tranc[c] = np;
	if(p == nil)	np->father = root;
	else {
		Complex *q = p->tranc[c];
		if(q->len == p->len + 1)	np->father = q;
		else {
			Complex *nq = NewComplex(p->len + 1);
			nq->father = q->father;
			q->father = np->father = nq;
			memcpy(nq->tranc,q->tranc,sizeof(q->tranc));
			for(; p != nil && p->tranc[c] == q; p = p->father)
				p->tranc[c] = nq;
		}
	}
	last = np;
}

int main()
{
	for(cin >> T; T--;) {
		Initialize();
		scanf("%s",s);
		int length = strlen(s);
		for(int i = 0; i < length; ++i)
			Add(s[i] - 'a');
		for(int i = 0; i < length; ++i)
			Add(s[i] - 'a');
		Complex *now = root;
		for(int i = 0; i < length; ++i)
			for(int j = 0; j < 26; ++j)
				if(now->tranc[j] != nil) {
					now = now->tranc[j];
					break;
				}
		printf("%d\n",now->len - length + 1);
	}
}


POJ 1509 Glass Beads 后缀自动机

标签:poj   后缀自动机   后缀树   

原文地址:http://blog.csdn.net/jiangyuze831/article/details/42802967

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