poj 2406 Power Strings (后缀数组 || KMP)
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 28859 | Accepted: 12045 |
Description
Input
Output
Sample Input
abcd
aaaa
ababab
.
Sample Output
1
4
3
Hint
Source
//42704K 2829MS C++ 2709B 2013-12-18 13:31:43
/* 题意:
给出一个由某个子串重复R次组成的字符串,求R的最大值 后缀数组:
KMP应该会简单些,因为此处要练习后缀数组,故用后缀数组。首先考虑用DA的话会TLE,
因为其时间复杂度为O(nlgn),数据太大(n=2000000)。
此处用dc3,dc3的算法没研究,只是套用其模板,dc3算法会比DA快些,在此处勉勉强强
的过了。先用dc3求出后缀数组,然后再求height数组,再穷举字符串长度len。求k能整除len
且suffix(1) 与 suffix(k+1) 最长前缀等于len-k。
在求最长公共前缀时,由于suffix(1)是固定的,利用height数组的特性,求出height数组
中每一个数到height[rank[0]]间的最小值即可。 */
#include<stdio.h>
#include<string.h>
#define N 2000005
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
int wa[N],wb[N],wv[N],ws[N];
int rank[N],height[N];
int sa[N],r[N];
char c[N];
int lcp[N]; //记录到height[rank[0]]的最小值
int Max(int a,int b)
{
return a>b?a:b;
}
int Min(int a,int b)
{
return a<b?a:b;
}
int cmp(int *y,int a,int b,int l)
{
return y[a]==y[b]&&y[a+l]==y[b+l];
} int c0(int *y,int a,int b)
{
return y[a]==y[b]&&y[a+]==y[b+]&&y[a+]==y[b+];
}
int c12(int k,int *y,int a,int b)
{
if(k==) return y[a]<y[b]||y[a]==y[b]&&c12(,y,a+,b+);
else return y[a]<y[b]||y[a]==y[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)
{
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;
}
void get_height(int n)
{
int i,j,k=;
for(i=;i<=n;i++) rank[sa[i]]=i;
for(i=;i<n;height[rank[i++]]=k)
for(k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k];k++);
return;
}
int main(void)
{
while(scanf("%s",c)!=EOF)
{
if(strcmp(c,".")==) break;
int n=strlen(c);
for(int i=;i<n;i++)
r[i]=c[i]+;
r[n]=;
dc3(r,sa,n+,);
get_height(n);
//for(int i=0;i<n;i++) printf("%d %d %d\n",i,rank[i],height[i]);
memset(lcp,,sizeof(lcp));
lcp[rank[]]=N;
for(int i=rank[]-;i>=;i--) lcp[i]=Min(lcp[i+],height[i+]);
for(int i=rank[]+;i<=n;i++) lcp[i]=Min(lcp[i-],height[i]);
//for(int i=0;i<=n;i++) printf("%d %d %d\n",rank[i],height[i],lcp[i]);
for(int k=;k<=n;k++) //遍历所有值
if(n%k== && lcp[rank[k]]==n-k){
printf("%d\n",n/k);
break;
}
}
return ;
}
/*
abcd
aaaa
ababab
*/
poj 2406 Power Strings (后缀数组 || KMP)的更多相关文章
- poj 2406 Power Strings 后缀数组解法
连续重复子串问题 poj 2406 Power Strings http://poj.org/problem?id=2406 问一个串能否写成a^n次方这种形式. 虽然这题用kmp做比较合适,但是我们 ...
- (简单) POJ 2406 Power Strings,扩展KMP。
Description Given two strings a and b we define a*b to be their concatenation. For example, if a = & ...
- POJ 2406 Power Strings next数组循环节应用、
题意:就给出个字符串做*的定义.a^0 = "" (the empty string) and a^(n+1) = a*(a^n). 题目要求n的最大值. 思路: 化简上面的 ...
- KMP POJ 2406 Power Strings
题目传送门 /* 题意:一个串有字串重复n次产生,求最大的n KMP:nex[]的性质应用,感觉对nex加深了理解 */ /************************************** ...
- poj 2406 Power Strings (kmp 中 next 数组的应用||后缀数组)
http://poj.org/problem?id=2406 Power Strings Time Limit: 3000MS Memory Limit: 65536K Total Submiss ...
- POJ 2406 Power Strings (KMP)
Power Strings Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 29663Accepted: 12387 Descrip ...
- poj 2406:Power Strings(KMP算法,next[]数组的理解)
Power Strings Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 30069 Accepted: 12553 D ...
- 【poj 2406】Power Strings 后缀数组DC3模板 【连续重复子串】
Power Strings 题意 给出一个字符串s,求s最多由几个相同的字符串重复而成(最小循环节的重复次数) 思路 之前学习KMP的时候做过. 我的思路是:枚举字符串的长度,对于当前长度k,判断\( ...
- POJ - 2406 Power Strings (后缀数组DC3版)
题意:求最小循环节循环的次数. 题解:这个题其实可以直接用kmp去求最小循环节,然后在用总长度除以循环节.但是因为在练后缀数组,所以写的后缀数组版本.用倍增法会超时!!所以改用DC3法.对后缀数组还不 ...
随机推荐
- 一篇SSM框架整合友好的文章(二)
上一篇讲述了DAO 层,mybatis实现数据库的连接,DAO层接口设计,以及mybtis和spring的整合.DAO层采用接口设计方式实现,接口和SQL实现的分离,方便维护.DAO层所负责的仅仅是接 ...
- 泉五培训Day3
T1 家庭作业 题目 [问题描述] 小P为了能高效完成作业,规定每项作业花一个单位时间. 他的学习日从0时刻开始,有100000个单位时间.在任一时刻,他都可以选择编号1~N的N项作业中的任意一项作业 ...
- Ansible工作架构和原理
特性 模块块化调用持定的模块,完成持定任务 有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块 支持自定义模块 基于Python语法头现 部署简单,基于python和SSH(默认已 ...
- python__高级 : 动态添加 对象属性, 类属性, 对象实例方法, 类静态方法, 类方法
给对象添加实例属性,可以直接这样 t.age = 18 ( 假设 t = Test() ) 给类添加类属性 , 也可以直接这样 Test.age = 18 那给对象添加实例方法,可以在类外面 ...
- Can't connect to local MySQL server through socket '/tmp/mysql.sock'
今天在连接mysql的时候出现了上面的错误, 很明显原因找不到/socket 文件 查了半天才发现原来是mysql没有开启 service mysqld start 开启之后在/tmp/目录下回自 ...
- 1016-06-首页20-封装工具条---UITableView控件距离顶部的间距问题----cell选中时的背景颜色设置
一.设置UITableView里面的顶部 cell 距离顶部的间距的三种方式: 方法 1. 直接设置: self.tableView.contentInset = UIEdgeInsetsMake(H ...
- P1338 末日的传说 逆序数对
题目描述 只要是参加jsoi活动的同学一定都听说过Hanoi塔的传说:三根柱子上的金片每天被移动一次,当所有的金片都被移完之后,世界末日也就随之降临了. 在古老东方的幻想乡,人们都采用一种奇特的方式记 ...
- [CodeForces954G]Castle Defense(二分答案+差分)
Description 题目链接 Solution 二分答案,套一个差分标记即可 每次放弓箭手显然越右边越优 Code #include <cstdio> #include <alg ...
- 笔记-git-git服务器安装及配置
笔记-git-git服务器安装及配置 1. GIT服务器简介 Git 可以使用四种主要的协议来传输数据:本地传输,SSH 协议,Git 协议和 HTTP 协议.下面分别介绍一下哪些情形应该使 ...
- 笔记-scrapy-setting
笔记-scrapy-setting 1. 简介 Scrapy设置允许您自定义所有Scrapy组件的行为,包括核心,扩展,管道和蜘蛛本身. 可以使用不同的机制来填充设置,每种机制都有不同的优先级 ...