POJ Glass Beads

Description

求字符串的最小循环表示.

Sol

SAM.

把原串复制一遍,建出SAM,然后每次选最小的一个跑 \(len\) 次,这就是最小循环表示的最后一个节点,然后 \(x-len+1\) 即为答案.

Code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

const int N = 20005;

int n,rt,lst,cnt,l;
int s[N];
int val[N],par[N],go[N][26];

inline int in(int x=0,char ch=getchar()){ while(ch>‘9‘ || ch<‘0‘) ch=getchar();
	while(ch>=‘0‘ && ch<=‘9‘) x=(x<<3)+(x<<1)+ch-‘0‘,ch=getchar();return x; }
inline int read(int l=0,char ch=getchar()){ while(ch>‘z‘ || ch<‘a‘) ch=getchar();
	while(ch>=‘a‘ && ch<=‘z‘) s[++l]=ch-‘a‘,ch=getchar();return l; }
void Extend(int w){
	int p=lst,np=++cnt;val[np]=val[p]+1,memset(go[np],0,sizeof(go[np]));
	while(p && !go[p][w]) go[p][w]=np,p=par[p];
	if(!p) par[np]=rt;
	else{
		int q=go[p][w];
		if(val[p]+1 == val[q]) par[np]=q;
		else{
			int nq=++cnt;
			val[nq]=val[p]+1;
			memcpy(go[nq],go[q],sizeof(go[q]));
			par[nq]=par[q];
			par[np]=par[q]=nq;
			while(p && go[p][w]==q) go[p][w]=nq,p=par[p];
		}
	}lst=np;
}
int work(){
	int x=rt;
	for(int i=1;i<=l;i++)
		for(int j=0;j<26;j++) if(go[x][j]){ x=go[x][j];break; }
	return val[x]>=l?val[x]-l:val[x];
}
int main(){
	n=in();
	for(int i=1;i<=n;i++){
		l=read(),rt=lst=cnt=1;
		val[rt]=par[rt]=0;memset(go[rt],0,sizeof(go[rt]));
		for(int i=l+1;i<=2*l;i++) s[i]=s[i-l];
		for(int i=1;i<=2*l;i++) Extend(s[i]);
		cout<<work()+1<<endl;
	}
}

  

时间: 2024-11-10 07:14:48

POJ Glass Beads的相关文章

[最小表示] poj 1509 Glass Beads

题目链接: http://poj.org/problem?id=1509 Glass Beads Time Limit: 3000MS   Memory Limit: 10000K Total Submissions: 2311   Accepted: 1343 Description Once upon a time there was a famous actress. As you may expect, she played mostly Antique Comedies most of

UVALive 5545 Glass Beads

Glass Beads Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 554564-bit integer IO format: %lld      Java class name: Main Once upon a time there was a famous actress. As you may expect, she played mostly

Glass Beads

Once upon a time there was a famous actress. As you may expect, she played mostly Antique Comedies most of all. All the people loved her. But she was not interested in the crowds. Her big hobby were beads of any kind. Many bead makers were working fo

PKU 1509 Glass Beads (最小表示法)

题意:有一个环形字符串,让你找一个位置切一刀使得字符串字母序最小,输出这个位置. 思路:可以看成两个字符串比较,一个是从下标0开始(0~n-1),一个从下标1开始(1~n-1,0). 然后两个指针i=0,j=1.从s[i]和s[j]开始比较第k个字符是否相同,当k==len时,返回i,j中的最小值.当s[i+k]和s[j+k]不相同时,若s[i+k]>s[j+k]则可见从s[i+1]到s[i+k]都不会是最小字典序的起始位置,所以i=i+k+1.当s[i+k]<s[j+k]时同理.若移动后i=

zoj 2006 Glass Beads

Glass Beadshttp://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1006 Time Limit: 2 Seconds      Memory Limit: 65536 KB Once upon a time there was a famous actress. As you may expect, she played mostly Antique Comedies most of all. All the peopl

SPOJ-BEADS UVA719 UVALive5545 POJ1509 ZOJ2006 Glass Beads【字符串环的最小】

Glass Beads Time Limit: 3000MS Memory Limit: 10000K Total Submissions: 5254 Accepted: 2943 Description Once upon a time there was a famous actress. As you may expect, she played mostly Antique Comedies most of all. All the people loved her. But she w

●POJ 1509 Glass Beads

题链: http://poj.org/problem?id=1509 题解: 给出一个字符串,有一个操作:把首字符放到末尾,形成新的串.求任意次操作后,字典序最小的串的首字母在原串中的位置.(这就是最小表示法?哈) 把原串翻倍,建立后缀自动机.然后在自动机上从起点往当前节点的较小的字母上跑len步即可.代码: #include<cstdio> #include<cstring> #include<iostream> #define MAXN 40050 #define

POJ 1509 Glass Beads 后缀自动机 模板 字符串的最小表示

http://poj.org/problem?id=1509 后缀自动机其实就是一个压缩储存空间时间(对节点重复利用)的储存所有一个字符串所有子串的trie树,如果想不起来长什么样子可以百度一下找个图回忆,从0开始到任意一个点的串都是字符串的子串. 有一些很好用的性质. 字符串的最小表示就是把一个字符串首尾相连再从任意一个地方断开产生的字典序最小的字符串,这个题是求最小表示的开头字母在原字符串中的下标(从1开始). 具体看实现吧,没什么可以解释的地方. 1 #include<iostream>

poj 1509 Glass Beads

题意:给你一个长度为n的字符串环,以位置i开始的顺时针长度为n的环构成的字符串有n个,问其中最小字典序的开始位置,有多种解时,输出起始位置最小的. 分析: 首先可以直接拼接两个长度为n的字符串,设原串为S[0],S[1]...S[n-1]则拼接后就是S'=S[0],S[1],...S[n-1],S[0],S[1],...S[n-1]. 那么问题中的n个长度为n的字符串中的任意一个,一定存在S'的某个后缀字符串的前缀与其相等. 我们现在要找最小字典序,则可以直接先求S'的后缀数组SA,然后: 1.