poj2406 连续重复子串
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 41110 | Accepted: 17099 |
Description
Input
Output
/*
poj2406 连续重复子串 给你一个字符串,请问最多能由任意字符串重复多少次得到 最开始用的是DA算法
想的是枚举长度然后进行一下判断即可,只需要判断Rank[0]和Rank[k]是否为n-k
(因为如果相等,0~k = k+1~2*k+1 .... 递推下去 整个串是0~k的子串不断
重复得到)
但是MLE.估计是处理RMQ时有问题,而且看了别人报告才发现这并不是最优方法。
因为我们求的是所有数到Rank[0],所以直接从rank[0]的位置往两边扫一遍就行了
但是DA算法nlog(n)好像会TLE- -
于是乎重新去搞了DC3的算法,才搞定 2600ms 而且感觉kmp更适合这个(看比人代码很短的样子) hhh-2016-03-13 18:11:02
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define lson (i<<1)
#define rson ((i<<1)|1)
const int maxn = 2000001; #define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
int wsf[maxn],wa[maxn],wb[maxn],wv[maxn],sa[maxn],Rank[maxn],
height[maxn],f[maxn];
int str[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++) wsf[i]=0;
for(i=0; i<n; i++) wsf[wv[i]]++;
for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
for(i=n-1; i>=0; i--) b[--wsf[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=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 getheight(int *r,int n)//n不保存最后的0
{
int i,j,k=0;
for(i=1; i<=n; i++) Rank[sa[i]]=i;
for(i=0; i<n; i++)
{
if(k)
k--;
else
k=0;
j=sa[Rank[i]-1];
while(r[i+k]==r[j+k])
k++;
height[Rank[i]]=k;
}
}
int rm[maxn];
char ts[maxn]; void iniRMQ(int len)
{
int to = Rank[0];
rm[to] = maxn;
for(int i = to - 1;i >= 0;i--)
{
if(height[i+1] < rm[i+1]) rm[i] = height[i+1];
else rm[i] = rm[i+1];
} for(int i = to+1;i <= len;i++)
{
if(height[i] < rm[i-1]) rm[i] = height[i];
else rm[i] = rm[i-1];
}
} int solve(int len)
{
for(int i = 1;i <= len/2;i++)
{
if(len % i) continue;
if(rm[Rank[i]] == len-i) return len/i;
}
return 1;
} int main()
{
while(scanf("%s",ts) != EOF)
{
if(ts[0] == '.')
break;
int len = strlen(ts);
for(int i = 0; i < len; i++)
str[i] = ts[i];
str[len] = 0; dc3(str,sa,len+1,300);
getheight(str,len);
iniRMQ(len);
printf("%d\n",solve(len));
}
return 0;
}
poj2406 连续重复子串的更多相关文章
- 【POJ 3693】Maximum repetition substring 重复次数最多的连续重复子串
后缀数组的论文里的例题,论文里的题解并没有看懂,,, 求一个重复次数最多的连续重复子串,又因为要找最靠前的,所以扫的时候记录最大的重复次数为$ans$,扫完后再后从头暴力扫到尾找重复次数为$ans$的 ...
- spoj687 后缀数组重复次数最多的连续重复子串
REPEATS - Repeats no tags A string s is called an (k,l)-repeat if s is obtained by concatenating k& ...
- POJ-3693-Maximum repetition substring(后缀数组-重复次数最多的连续重复子串)
题意: 给出一个串,求重复次数最多的连续重复子串 分析: 比较容易理解的部分就是枚举长度为L,然后看长度为L的字符串最多连续出现几次. 既然长度为L的串重复出现,那么str[0],str[l],str ...
- poj 3693 后缀数组 重复次数最多的连续重复子串
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8669 Acc ...
- POJ 3693 Maximum repetition substring(连续重复子串)
http://poj.org/problem?id=3693 题意:给定一个字符串,求重复次数最多的连续重复子串. 思路: 这道题确实是搞了很久,首先枚举连续子串的长度L,那么子串肯定包含了r[k], ...
- Repeats SPOJ - REPEATS(重复次数最多的连续重复子串)
论文题例8 https://blog.csdn.net/queuelovestack/article/details/53031731这个解释很好 其实,当枚举的重复子串长度为i时,我们在枚举r[i* ...
- 【poj3693-重复次数最多的连续重复子串】后缀数组
题意:给定一个串,长度<=10^5,求它重复次数最多的连续重复子串(输出字典序最小的那个). 例如ccabcabc,答案就是abcabc 一开始没想清楚,结果调了好久. 原理: 按照L划分,因为 ...
- POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS Memory Li ...
- SPOJ - REPEATS —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/SPOJ-REPEATS REPEATS - Repeats no tags A string s is called an (k,l ...
随机推荐
- (function(root,factory){})(this,function($){}) 一个立即执行的匿名函数自调
因为新公司用到ocx 我就开始看原来的代码 无意中发现这个 可能原来比较low吗(虽然现在也很low吧)没发现这个东东 还可以这样写 于是乎我开始了探索 完整代码如下 HTML <div id= ...
- python小练习之二
title: python小练习之二 tags: 新建,模板,小书匠 grammar_cjkRuby: true --- python小练习之二 需求:实现用户登录,用户名和密码保存到文件里,连续输入 ...
- Oracle数据库游标精解
游标 定义:标识结果集中数据行的一种容器(CURSOR),游标允许应用程序对查询语句返回的行结果集中的每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作.实际上是一种能从包括多条数据记录 ...
- it's a big trick
今天,正式的登上了我注册已久的博客园,最初注册园子得出发点是记录生活点滴和学习工作的心得的,那就不忘初心,从头开始吧. 从校园到工作,从东北到南方 我们毕业啦 谁说毕业遥遥无期,转眼就要各奔东西. 是 ...
- EasyUI 修改 Messager 消息框大小
需求是要修改确认消息窗口的大小. 简单的调用方法是这样的: $.messager.confirm('操作确认', '确定批量编辑文章?', function (r) { ... } 这个时候生成的弹窗 ...
- Python内置函数(18)——bin
英文文档: bin(x) Convert an integer number to a binary string. The result is a valid Python expression. ...
- emqtt 试用(七)追踪
追踪 EMQ 消息服务器支持追踪来自某个客户端(Client)的全部报文,或者发布到某个主题(Topic)的全部消息. 追踪客户端(Client): ./bin/emqttd_ctl trace cl ...
- Centos7.x:开机启动服务的配置和管理
一.开机启动服务的配置 1.创建服务配置(权限754) vim /usr/lib/systemd/system/nginx.service 文件内容解释 [Unit]:服务的说明Description ...
- BlueMix - IBM的Paas云计算平台
Bluemix,2015年年中,IBM推出了名为Bluemix的云计算平台.这一"平台即服务"的PaaS云将帮助开发者更快的进行应用开发和部署. Bluemix正是IBM回应这 ...
- 您的 Java 代码安全吗 — 还是暴露在外? 【转】
在开发 Java Web 应用程序时,您需要确保应用程序拥有完善的安全性特征补充.这里在谈到 Java 安全性时,我们并不谈及 Java 语言提供的安全性 API,也不涉及使用 Java 代码来保护应 ...