电源串
时间限制: 3000MS   内存限制: 65536K
提交总数: 53037   接受: 22108

描述

给定两个字符串a和b,我们定义a * b是它们的连接。例如,如果a =“abc”和b =“def”,那么a * b =“abcdef”。如果我们将连接看作是乘法,则用正常的方式定义非负整数的指数:a
^ 0 =“”(空字符串)和a ^(n + 1)= a *(a ^ n)。

输入

每个测试用例都是一行代表s的输入,一串可打印的字符。s的长度至少为1,不会超过100万字符。在最后一个测试用例之后包含句点的行。

产量

对于每一个s,你应该打印出最大的n,这样对于某个字符串a,s = a ^ n。

示例输入

A B C D
AAAA
ABABAB

示例输出

1
4
3

暗示

这个问题有巨大的投入,使用scanf而不是cin来避免超时。

题解

这道题正解应该是KMP,我之前的KMP复习的博客里有解释,这里就不赘述了
主要是根据如果最后一位的最长等于的后缀的前缀长与总长的差刚好是len的因子,说明len就是最大循环节
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define fo(i,x,y) for (int i = (x); i <= (y); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 1000005,maxm = 100005,INF = 1000000000; char P[maxn];
int n,f[maxn]; void getf(){
int j = f[0] = -1,i = 0;
while (i < n){
while (j != -1 && P[j] != P[i]) j = f[j];
f[++i] = ++j;
}
} int main()
{
while (true){
fgets(P,maxn,stdin);
n = strlen(P) - 1;
if (n == 1 && P[0] == '.') break;
getf();
if (n % (n - f[n]) == 0) printf("%d\n",n/(n - f[n]));
else printf("1\n");
}
return 0;
}

为什么突发奇想又写一次这道题呢?
因为今天在练后缀数组时看到有博主用后缀数组写了,不过倍增的后缀数组会T  QAQ【我只会倍增求法】
但也拍上来,主要是理解了lcp的求法
代码【非正解】:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 1000005,maxm = 10005,INF = 1000000000;
inline int RD(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
char s[maxn];
int n,sa[maxn],rank[maxn],height[maxn],t1[maxn],t2[maxn],m = 300,c[maxn];
int lcp[maxn];
void SA(){
int *x = t1,*y = t2;
for (int i = 0; i <= m; i++) c[i] = 0;
for (int i = 1; i <= n; i++) c[x[i] = s[i]]++;
for (int i = 1; i <= m; i++) c[i] += c[i - 1];
for (int i = n; i >= 1; i--) sa[c[x[i]]--] = i;
for (int k = 1; k <= n; k <<= 1){
int p = 0;
for (int i = n - k + 1; i <= n; i++) y[++p] = i;
for (int i = 1; i <= n; i++) if (sa[i] - k > 0) y[++p] = sa[i] - k;
for (int i = 0; i <= m; i++) c[i] = 0;
for (int i = 1; i <= n; i++) c[x[y[i]]]++;
for (int i = 1; i <= m; i++) c[i] += c[i - 1];
for (int i = n; i >= 1; i--) sa[c[x[y[i]]]--] = y[i];
swap(x,y);
p = 1; x[sa[1]] = 1;
for (int i = 2; i <= n; i++)
x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) ? p : ++p;
if (p >= n) break;
m = p;
}
for (int i = 1; i <= n; i++) rank[sa[i]] = i;
int k = 0;
for (int i = 1; i <= n; i++){
if (k) k--;
int j = sa[rank[i] - 1];
while (s[i + k] == s[j + k]) k++;
height[rank[i]] = k;
}
}
void LCP(){
int k = rank[1]; lcp[k] = n;
for (int i = k - 1; i >= 1; i--) lcp[i] = min(lcp[i + 1],height[i + 1]);
for (int i = k + 1; i <= n; i++) lcp[i] = min(lcp[i - 1],height[i]);
}
bool check(int len){return lcp[rank[len + 1]] == n - len;}
int main(){
while (true){
m = 300;
scanf("%s",s + 1); if(s[1] == '.') break;
n = strlen(s + 1);
SA();
LCP();
int E = (int)sqrt(n),ans = 0;
for (int i = 1; i <= E; i++){
if (n % i) continue;
if (check(i)) ans = max(ans,n / i);
if (check(n / i)) ans = max(ans,i);
}
printf("%d\n",ans);
}
return 0;
}

最新文章

  1. IoC和DI的理解
  2. c++引用总结
  3. &lt;转&gt;SQL语句执行顺序说明
  4. WebApi 2:属性路由 [Route()],attribute routing
  5. R语言apply函数族笔记
  6. 阿牛OCX编程助手
  7. zboot/piggyback.c
  8. Javascript中函数的四种调用方式
  9. Tomcat 管理页面
  10. fedora -- java多版本切换
  11. js数组(一)
  12. 使用perf生成Flame Graph(火焰图)
  13. 【Visual C++】游戏编程学习笔记之七:键盘输入消息
  14. WebApi 身份认证解决方案:Basic基础认证
  15. PAT乙级考前总结(四)
  16. 利用谷歌网站的翻译网站,实现谷歌翻译api
  17. Codeforces Round #432 Div. 1
  18. 内存proc详解
  19. nmap扫描内网存活机器脚本
  20. 关于js的对象原型继承(二)

热门文章

  1. (转)IP地址分配原理
  2. 微信小程序 提示框延时跳转
  3. 右键添加git-bash
  4. python中协程实现的本质以及两个封装协程模块greenle、gevent
  5. Java——equals方法---18.10.18
  6. docker学习(三) 安装docker的web可视化管理工具
  7. Linux:如何获取打开文件和文件描述符数量
  8. CSS3实现加载数据动画1
  9. NOI2018 游记
  10. table调整td宽度整理-完美解决--费元星前端