您的位置:首页 > 其它

POJ 2406 Power Strings

2015-10-10 21:33 393 查看
Description

Given two strings a and b we define a*b to be their concatenation. For example, if a = “abc” and b = “def” then a*b = “abcdef”. If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = “” (the empty string) and a^(n+1) = a*(a^n).

Input

Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.

Output

For each s you should print the largest n such that s = a^n for some string a.

Sample Input

abcd

aaaa

ababab

.

Sample Output

1

4

3

题意 : 给定字符串,问最多能找出几个循环节。

思路:论文里写的很清楚了论文

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>

using namespace std;
#define MAXN 10000010*3
#define F(x) ((x)/3 + ((x)%3 == 1 ? 0 : tb))
#define G(x) ((x) < tb?(x)*3 + 1:((x) - tb)*3+2)
int wa[MAXN], wb[MAXN], wv[MAXN], wss[MAXN];
int c0(int *r, int a, int b)
{
return r[a] == r[b] && r[a + 1] == r[b + 1] && r[a + 2] == r[b + 2];
}
int c12(int k, int *r, int a, int b)
{
if(k == 2)
return r[a] < r[b] || (r[a] == r[b] && c12(1, r, a + 1, b + 1));
else return r[a] < r[b] || (r[a] == r[b] && wv[a + 1] < wv[b + 1]);
}
void _sort(int *r, int *a, int *b, int n, int m)
{
int i;
for( i = 0; i < n; i++) wv[i] = r[a[i]];
for( i = 0; i < m; i++) wss[i] = 0;
for( i = 0; i < n; i++) wss[wv[i]]++;
for( i = 1; i < m; i++) wss[i] += wss[i - 1];
for( i = n - 1; i >= 0; i--) b[--wss[wv[i]]] = a[i];
}
void dc3(int *r, int *sa, int n, int m)
{
int i, j, *rn = r + n;
int *san = sa + n, ta = 0, tb = (n + 1)/3, tbc = 0, p;
r
= r[n+1] = 0;
for( i = 0; i < n; i++) if(i%3 != 0) wa[tbc++] = i;
_sort(r + 2, wa, wb, tbc, m);
_sort(r + 1, wb, wa, tbc, m);
_sort(r, wa, wb, tbc, m);
for( p = 1, rn[F(wb[0])] = 0, i = 1; i < tbc; i++)
rn[F(wb[i])] = c0(r, wb[i - 1], wb[i])? p - 1 : p ++;
if(p < tbc) dc3(rn, san, tbc, p);
else for( i = 0; i < tbc; i++) san[rn[i]] = i;
for( i = 0; i < tbc; i++)
if(san[i] < tb) wb[ta++] = san[i] * 3;
if(n % 3 == 1) wb[ta++] = n - 1;
_sort(r, wb, wa, ta, m);
for( i = 0; i < tbc; i++) wv[wb[i] = G(san[i])] = i;
for( i = 0, j = 0, p = 0; i < ta && j < tbc; p ++)
sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++]: wb[j++];
for( ; i < ta; p++) sa[p] = wa[i++];
for( ; j < tbc; p++) sa[p] = wb[j ++];
}

void da(int str[], int sa[], int _rank[], int height[], int n, int m)
{
for( int i = n; i < n*3; i++)
str[i] = 0;
dc3(str, sa, n + 1, m);
int i, j, k = 0;
for( i = 0; i <= n; i++) _rank[sa[i]] = i;
for( i = 0; i < n; i++)
{
if(k) k --;
j = sa[_rank[i] - 1];
while(str[i+k] == str[j+k]) k++;
height[_rank[i]] = k;
}
}
char s[MAXN];
int str[MAXN], sa[MAXN], _rank[MAXN], height[MAXN];
int n, m;
int mink[MAXN];
int main()
{
while(scanf("%s",&s))
{
int len =strlen(s);
if(s[0] == '.') break;
for( int i = 0; i < len; i++)
str[i] = s[i];
da(str, sa, _rank, height, len, 128);
int ans = 0;

mink[_rank[0]] = MAXN;

for( int i = _rank[0] - 1; i >= 0 ; i--)
mink[i] = min(mink[i+1], height[i+1]);
for( int i = _rank[0] + 1; i <= len; i++)
mink[i] = min(mink[i-1], height[i]);
//for( int i = 0; i <= len; i++)
//  printf("%d ---- %d\n",i, mink[i]);
for( int i = 1; i <= len; i++)
if(len % i == 0 && mink[_rank[i]] == len - i )
{
ans = len/i;
break;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: