连续重复子串问题

poj 2406 Power Strings

http://poj.org/problem?id=2406

问一个串能否写成a^n次方这种形式。

虽然这题用kmp做比较合适,但是我们还是用后缀数组做一做,巩固后缀数组的能力。

对于一个串,如果能写出a^n这种形式,我们可以暴力枚举循环节长度L,那么后缀suffix(1)和suffix(1 + L)的LCP应该就是 lenstr - L。如果能满足,那就是,不能,就不是。

这题的话da算法还是超时,等我学了DC3再写上来。

其实这题可以不用枚举,考虑到如果能写成a^n这种形式,那么其循环节长度必定为 lenstr - height[rank[1]]

给个图可能会更清楚

如果是循环节,那么height[rank[1]]就是第1位的排名前后的lcp,肯定是第二个循环节那里的。

然后暴力判断一下就行~dc3, 2750ms才能卡过去

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = * + ;
const int N = maxn;
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
int r[maxn];
int wa[maxn],wb[maxn],wv[maxn],WS[maxn];
int sa[maxn];
int c0(int *r,int a,int b) {
return r[a]==r[b]&&r[a+]==r[b+]&&r[a+]==r[b+];
}
int c12(int k,int *r,int a,int b) {
if(k==) return r[a]<r[b]||r[a]==r[b]&&c12(,r,a+,b+);
else return r[a]<r[b]||r[a]==r[b]&&wv[a+]<wv[b+];
}
void sort(int *r,int *a,int *b,int n,int m) {
int i;
for(i=; i<n; i++) wv[i]=r[a[i]];
for(i=; i<m; i++) WS[i]=;
for(i=; i<n; i++) WS[wv[i]]++;
for(i=; i<m; i++) WS[i]+=WS[i-];
for(i=n-; i>=; i--) b[--WS[wv[i]]]=a[i];
return;
}
void dc3(int *r,int *sa,int n,int m) { //涵义与DA 相同
int i,j,*rn=r+n,*san=sa+n,ta=,tb=(n+)/,tbc=,p;
r[n]=r[n+]=;
for(i=; i<n; i++) if(i%!=) wa[tbc++]=i;
sort(r+,wa,wb,tbc,m);
sort(r+,wb,wa,tbc,m);
sort(r,wa,wb,tbc,m);
for(p=,rn[F(wb[])]=,i=; i<tbc; i++)
rn[F(wb[i])]=c0(r,wb[i-],wb[i])?p-:p++;
if(p<tbc) dc3(rn,san,tbc,p);
else for(i=; i<tbc; i++) san[rn[i]]=i;
for(i=; i<tbc; i++) if(san[i]<tb) wb[ta++]=san[i]*;
if(n%==) wb[ta++]=n-;
sort(r,wb,wa,ta,m);
for(i=; i<tbc; i++) wv[wb[i]=G(san[i])]=i;
for(i=,j=,p=; i<ta && j<tbc; p++)
sa[p]=c12(wb[j]%,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;
}
int rank[maxn], height[maxn];
void calheight(int *r,int *sa,int n) { // 此处N为实际长度
int i,j,k=; // height[]的合法范围为 1-N, 其中0是结尾加入的字符
for(i=; i<=n; i++) rank[sa[i]]=i; // 根据SA求RANK
for(i=; i<n; height[rank[i++]] = k ) // 定义:h[i] = height[ rank[i] ]
for(k?k--:,j=sa[rank[i]-]; r[i+k]==r[j+k]; k++); //根据 h[i] >= h[i-1]-1 来优化计算height过程
}
char str[maxn];
void work() {
int lenstr = strlen(str);
for (int i = ; i < lenstr; ++i) r[i] = str[i];
r[lenstr] = ;
dc3(r, sa, lenstr + , );
calheight(r, sa, lenstr);
int t = lenstr - height[rank[]];
if (t == lenstr || lenstr % t != ) {
printf("1\n");
} else {
for (int i = t; i < lenstr; i += t) {
for (int j = ; j < t; ++j) {
if (str[j] != str[i + j]) {
printf("1\n");
return;
}
}
}
printf("%d\n", lenstr / t);
}
} int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
while (scanf("%s", str) != EOF) {
if (str[] == '.') break;
work();
}
return ;
}

poj 2406 Power Strings 后缀数组解法的更多相关文章

  1. poj 2406 Power Strings (后缀数组 || KMP)

    Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 28859   Accepted: 12045 D ...

  2. POJ 2406 Power Strings next数组循环节应用、

    题意:就给出个字符串做*的定义.a^0 = "" (the empty string) and a^(n+1) = a*(a^n).    题目要求n的最大值. 思路: 化简上面的 ...

  3. KMP POJ 2406 Power Strings

    题目传送门 /* 题意:一个串有字串重复n次产生,求最大的n KMP:nex[]的性质应用,感觉对nex加深了理解 */ /************************************** ...

  4. poj 2406 Power Strings (kmp 中 next 数组的应用||后缀数组)

    http://poj.org/problem?id=2406 Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submiss ...

  5. POJ 2406 Power Strings (KMP)

    Power Strings Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 29663Accepted: 12387 Descrip ...

  6. 【poj 2406】Power Strings 后缀数组DC3模板 【连续重复子串】

    Power Strings 题意 给出一个字符串s,求s最多由几个相同的字符串重复而成(最小循环节的重复次数) 思路 之前学习KMP的时候做过. 我的思路是:枚举字符串的长度,对于当前长度k,判断\( ...

  7. POJ - 2406 Power Strings (后缀数组DC3版)

    题意:求最小循环节循环的次数. 题解:这个题其实可以直接用kmp去求最小循环节,然后在用总长度除以循环节.但是因为在练后缀数组,所以写的后缀数组版本.用倍增法会超时!!所以改用DC3法.对后缀数组还不 ...

  8. poj 2406:Power Strings(KMP算法,next[]数组的理解)

    Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 30069   Accepted: 12553 D ...

  9. KMP + 求最小循环节 --- POJ 2406 Power Strings

    Power Strings Problem's Link: http://poj.org/problem?id=2406 Mean: 给你一个字符串,让你求这个字符串最多能够被表示成最小循环节重复多少 ...

随机推荐

  1. Listen 82

    Doc Calls Deconditioning a Condition Doctors know a lot about prescribing medications. "Take tw ...

  2. 基于 bi-LSTM和CRF的中文命名实体识别

    follow: https://github.com/zjy-ucas/ChineseNER  这里边主要识别的实体如图所示,其实也就主要识别人名PER,机构ORG和地点LOC: B表示开始的字节,I ...

  3. linux命令学习笔记-md5sum 命令详解

    前言 在网络传输.设备之间转存.复制大文件等时,可能会出现传输前后数据不一致的情况.这种情况在网络这种相对更 不稳定的环境中,容易出现.那么校验文件的完整性,也是势在必行的. 使用说明 md5sum命 ...

  4. 【Shell】通配符与特殊符号

    ——来自<鸟哥的Linux私房菜> 在 bash 的操作环境中还有一个非常有用的功能,那就是通配符 (wildcard) ! 我们利用 bash 处理数据就更方便了!底下列出一些常用的通配 ...

  5. ACM学习历程——HDU 5014 Number Sequence (贪心)(2014西安网赛)

    Description There is a special number sequence which has n+1 integers. For each number in sequence, ...

  6. WPF TextBox PreviewTextInput handle IME (chinese)

    今天调试自己写的WPF的Behavior, 是关于TextBox只能输入数据或者小数点的. 发现有个问题, 就是英文IME下字母等等都能过滤, 但是一旦切换到中文输入法, 就会发现在OnPreview ...

  7. nginx中有关命令和日志切割,配置文件加载的详细阐述

    一.Nginx简介 Nginx (“engine x”) 是俄罗斯人Igor Sysoev(塞索耶夫)编写的一款高性能的 HTTP 和反向代理服务器.Nginx 已经在俄罗斯最大的门户网站── Ram ...

  8. day1 java基础回顾-内省

    为什么要学内省? 开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性. 内省是用于操作j ...

  9. SVN needs-lock 设置强制只读属性【转】

    https://www.jianshu.com/p/5942ab19620b 设置后向svn服务器添加文件时,会自动带上svn:needs-lock属性,默认是只读的要签出才能修改,以避免不必要的编辑 ...

  10. C# ConfigurationManager 类的使用

    一.前言 在项目中,我们习惯使用 ConfigurationManager 来读取一些常量.如链接数据库字符串.一些需配置的数据(微信.QQ.支付宝)等的配置.我们需要把这些数据记录在 app.con ...