【poj2406】 Power Strings

http://poj.org/problem?id=2406 (题目链接)

题意

  给定一个字符串 L,已知这个字符串是由某个字符串 S 重复 R 次而得到的, 求 R 的最大值。

Solution

  后缀数组论文题,然而nlogn的倍增竟然TLE了,那给3s是什么意思→_→

  做法比较简单,穷举字符串 S 的长度 k,然后判断是否满足。判断的时候,先看字符串 L 的长度能否被 k 整除,再看 suffix(1)和 suffix(k+1)的最长公共前缀是否等于 n-k。在询问最长公共前缀的时候,suffix(1)是固定的,所以 RMQ 问题没有必要做所有的预处理,只需求出 height 数组中的每一个数到 height[rank[1]]之间的最小值即可。整个做法的时间复杂度为 O(n)。

  这是论文里面的后缀数组做法,而我们用KMP就是从后往前算。

代码

// poj2406
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 1<<30
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

const int maxn=1000010;
int next[maxn],n;
char s[maxn];

void calnext() {
	next[1]=0;
	for (int i=2,j=0;i<=n;i++) {
		while (j && s[i]!=s[j+1]) j=next[j];
		if (s[i]==s[j+1]) j++;
		next[i]=j;
	}
}
int main() {
	while (scanf("%s",s+1)!=EOF) {
		if (s[1]=='.') break;
		n=strlen(s+1);
		calnext();
		for (int i=next[n];i>=0;i=next[i])
			if (n%(n-i)==0) {printf("%d\n",n/(n-i));break;}
	}
    return 0;
}

 

posted @ 2017-01-12 10:19  MashiroSky  阅读(158)  评论(0编辑  收藏  举报