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
Hint
This problem has huge input, use scanf instead of cin to avoid time limit exceed.
題意: 給出一個字符串, 詢問該串最多由幾個循環串組成
思路:
我們可以發現當一個串由長度爲i的子串循環組成時
1: rank[0] = rank[i] + 1
2: len % i == 0
3: heig[rak[0]] == len - i
對於第一點當前串如果是由該串循環組成, 則第一個字符開始的循環串一定與第i個字符開始的循環串排名相鄰
所以 rank[0] = rank[i] + 1
對於第二點長度必定整除纔行
第三點
顯然第一個字符開始的循環串跟上一個排名的循環串的LCP = len - i
這個差值i即是循環串的長度
例如ababab
ababab與abab 的LCP = 4 = 6 - 2
PS:這題求SA使用倍增算法, 您將會得到
所以使用DC3吧, 不過這DC3我也看不懂, 也不會改(網上偷份拿着用吧), 下標從0開始輸入的串可真是難受
//#include <bits/stdc++.h>
#include <time.h>
#include <string>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <functional>
#include <set>
#include <map>
#include <queue>
//#include <unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#ifdef LOCAL
#define debug(x) cout << "[" __FUNCTION__ ": " #x " = " << (x) << "]\n"
#define TIME cout << "RuningTime: " << clock() << "ms\n", 0
#else
#define TIME 0
#endif
#define hash_ 1000000009
#define Continue(x) { x; continue; }
#define Return(x) { x; return; }
#define Break(x) { x; break; }
const int mod = 1e9 + 7;
const int N = 3e6 + 10;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
#define gc p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
inline int read(){ static char buf[1000000], *p1 = buf, *p2 = buf; register int x = false; register char ch = gc; register bool sgn = false; while (ch != '-' && (ch < '0' || ch > '9')) ch = gc; if (ch == '-') sgn = true, ch = gc; while (ch >= '0'&& ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc; return sgn ? -x : x; }
ll fpow(ll a, int b, int mod) { ll res = 1; for (; b > 0; b >>= 1) { if (b & 1) res = res * a % mod; a = a * a % mod; } return res; }
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
int len;
char s[N];
int sa[N], rak[N], heig[N], r[N], wa[N], wb[N], wv[N], wws[N];
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++) wws[i] = 0;
for (i = 0; i < n; i++) wws[wv[i]]++;
for (i = 1; i < m; i++) wws[i] += wws[i - 1];
for (i = n - 1; i >= 0; i--) b[--wws[wv[i]]] = a[i];
return;
}
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 dc3(int *r, int *sa, int n, int m){
int i, j, *rn = r + n, *san = sa + n, ta = 0, tb = (n + 1) / 3, tbc = 0, p;
r[n] = 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++];
return;
}
void calheight(int *r, int *sa, int n)
{
int i, j, k = 0;
for (i = 1; i <= n; ++i) rak[sa[i]] = i;
for (i = 0; i < n; heig[rak[i++]] = k)
for (k ? k-- : 0, j = sa[rak[i] - 1]; r[i + k] == r[j + k]; ++k);
return;
}
void solve()
{
for (int i = 1; i <= len; i++)
{
if (len % i == 0 && rak[0] == rak[i] + 1 && heig[rak[0]] == len - i)
Return(cout << len / i << endl)
}
cout << "1" << endl;
return ;
}
int main()
{
#ifdef LOCAL
freopen("D:/input.txt", "r", stdin);
#endif
while (~scanf("%s", s))
{
if (!strcmp(s, "."))
break;
len = strlen(s);
for (int i = 0; i < len; i++)
r[i] = s[i];
r[len] = 0;
dc3(r, sa, len + 1, 200);
calheight(r, sa, len);
solve();
}
return TIME;
}