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

Power Strings
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 27003   Accepted: 11311

Description

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 思路:
理解next数组,利用next数组进行巧妙求解
 #include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
#define MAX 1000000 void get_next(char *str,int *next)
{
int i=,j=-;
int tlen=strlen(str);
next[]=-;
while(i<tlen)
{
if(j==-||str[i]==str[j])
{
i++;
j++;
if(str[i]!=str[j])
next[i]=j;
else
next[i]=next[j];
}
else
j=next[j];
}
}
char str[MAX+];
int next[MAX+];
int main()
{
int t=;
while(~scanf("%s",str))
{
if(str[]=='.') break;
get_next(str,next);
int len = strlen(str);
// for(int i=0;i<=len;i++) cout<<next[i]<<" "; cout<<endl;
if(len%(len-next[len])==) //next[len]为匹配到len时失配所要跳到的上一个匹配点,len-next[len]即为一个循环节
printf("%d\n",len/(len-next[len]));
else
printf("1\n");
}
return ;
}

(后缀数组)思路:

给定一个字符串L,已知这个字符串是由某个字符串S重复R次而得到的,求R的最大值。

  算法分析:

  做法比较简单,穷举字符串S的长 k,然后判断是否满足。判断的时候,先看字符串L的长度能否被k整除,再看suffix(1)和suffix(k+1)的最长公共前缀是否等于n-k。在询问最长公共前缀的时候,suffix(1)是固定的,所以RMQ问题没有必要做所有的预处理,只需求出height数组中的每一个数到height[rank[1]]之间的最小值即可。整个做法的时间复杂度为O(n)。

以下是我超时代码:(尼玛滴不科学呀!!!)

TLE代码:跪求大神赐教!!!

 #include <iostream>
#include <stdio.h>
#include<string.h> using namespace std; #define maxn 1100000 #define cls(x) memset(x, 0, sizeof(x)) int wa[maxn],wb[maxn],wv[maxn],wss[maxn]; int cmp(int *r,int a,int b,int l){return r[a]==r[b]&&r[a+l]==r[b+l];} //倍增算法
void da(char *r,int *sa,int n,int m)
{
cls(wa);
cls(wb);
cls(wv);
int i,j,p,*x=wa,*y=wb,*t; //基数排序
for(i=;i<m;i++) wss[i]=;
for(i=;i<n;i++) wss[x[i]=r[i]]++;
for(i=;i<m;i++) wss[i]+=wss[i-];
for(i=n-;i>=;i--) sa[--wss[x[i]]]=i; // 在第一次排序以后,rank数组中的最大值小于p,所以让m=p。整个倍增算法基本写好,代码大约25行。
for(j=,p=;p<n;j*=,m=p)
{
//接下来进行若干次基数排序,在实现的时候,这里有一个小优化。基数排序要分两次,第一次是对第二关键字排序,第二次是对第一关键字排序。对第二关键字排序的结果实际上可以利用上一次求得的sa直接算出,没有必要再算一次
for(p=,i=n-j;i<n;i++) y[p++]=i;
for(i=;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; //其中变量j是当前字符串的长度,数组y保存的是对第二关键字排序的结果。然后要对第一关键字进行排序,
for(i=;i<n;i++) wv[i]=x[y[i]];
for(i=;i<m;i++) wss[i]=;
for(i=;i<n;i++) wss[wv[i]]++;
for(i=;i<m;i++) wss[i]+=wss[i-];
for(i=n-;i>=;i--) sa[--wss[wv[i]]]=y[i]; //这样便求出了新的sa值。在求出sa后,下一步是计算rank值。
for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
} int rank[maxn],height[maxn]; //得到height数组:排名相邻的两个后缀的最长公共前缀
void calheight(char *r,int *sa,int n)
{
cls(rank);
cls(height);
int i,j,k=; for(i=;i<n;i++) rank[sa[i]]=i;
// for(i=0;i<n;i++) printf("%d ",rank[i]); putchar(10); system("pause"); for(i=;i<n;height[rank[i++]]=k)
for(k?k--:,j=sa[((rank[i]-<)?:rank[i]-)];r[i+k]==r[j+k]&&i!=j;k++);
return;
} char ca[maxn];
int sa[maxn];
int N;
int minh[maxn]; int main()
{
int i;
while (~scanf("%s",ca))
{
N = strlen(ca);
if(ca[]=='.') break;
ca[N] = '#';
N++;
da(ca, sa, N, );
calheight(ca,sa,N); // for(i=0;i<N;i++) cout<<rank[i]<<" "; cout<<endl;
// for(i=0;i<N;i++) cout<<height[i]<<" "; cout<<endl; // for(i=0;i<N;i++) cout<<sa[i]<<" "; cout<<endl;
int i; int mins = height[rank[]];
for(i=rank[];i>;i--)
{
if(mins>height[i])
{
mins = height[i];
}
minh[i-] = mins;
}
mins = height[rank[]];
for(i=rank[];i<N;i++)
{
if(mins>height[i])
{
mins = height[i];
}
minh[i] = mins;
} for (i=;i<N;i++)
{
if ((N-) % i==&&minh[rank[i]]==N--i)
{
printf("%d\n",(N-) / i);
break;
}
}
}
return ;
}

poj 2406 Power Strings (kmp 中 next 数组的应用||后缀数组)的更多相关文章

  1. POJ 2406 Power Strings (KMP)

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

  2. poj 2406 Power Strings kmp算法

    点击打开链接 Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 27368   Accepted:  ...

  3. poj 2406 Power Strings(KMP变形)

    Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 28102   Accepted: 11755 D ...

  4. POJ 2406 Power Strings KMP算法之next数组的应用

    题意:给一个字符串,求该串最多由多少个相同的子串相接而成. 思路:只要做过poj 1961之后,这道题就很简单了.poj 1961 详细题解传送门. 假设字符串的长度为len,如果 len % (le ...

  5. POJ 2406 - Power Strings - [KMP求最小循环节]

    题目链接:http://poj.org/problem?id=2406 Time Limit: 3000MS Memory Limit: 65536K Description Given two st ...

  6. POJ 2406 Power Strings KMP运用题解

    本题是计算一个字符串能完整分成多少一模一样的子字符串. 原来是使用KMP的next数组计算出来的,一直都认为是能够利用next数组的.可是自己想了非常久没能这么简洁地总结出来,也仅仅能查查他人代码才恍 ...

  7. POJ 2406 Power Strings KMP求周期

    传送门 http://poj.org/problem?id=2406 题目就是求循环了几次. 记得如果每循环输出为1.... #include<cstdio> #include<cs ...

  8. poj 2406 Power Strings KMP匹配

    对于数组s[0~n-1],计算next[0~n](多计算一位). 考虑next[n],如果t=n-next[n],如果n%t==0,则t就是问题的解,否则解为1. 这样考虑: 比方字符串"a ...

  9. poj 2406 Power Strings 后缀数组解法

    连续重复子串问题 poj 2406 Power Strings http://poj.org/problem?id=2406 问一个串能否写成a^n次方这种形式. 虽然这题用kmp做比较合适,但是我们 ...

随机推荐

  1. JAVA_eclipse 保留Java文件时自动格式化代码和优化Import

    Eclipse 保存Java文件时自动格式化代码和优化Import Eclipse中format代码的快捷方式是ctrl+shift+F,如果大家想保存 java文件的时候 自动就格式化代码+消除不必 ...

  2. 自动化分析工具PSSDIAG

    微软有个内部工具--PSSDIAG,它能收集非常多的信息,仅需要简单的配置和操作步骤. 下载地址: http://diagmanager.codeplex.com 默认安装路径: C:\Program ...

  3. MyBatis6:MyBatis集成Spring事务管理(下篇)

    前言 前一篇文章<MyBatis5:MyBatis集成Spring事务管理(上篇)>复习了MyBatis的基本使用以及使用Spring管理MyBatis的事务的做法,本文的目的是在这个的基 ...

  4. 简单的jquery选择器的实现

    function getByClass(oParent,oClass){    if(document.getElementsByClassName){         return document ...

  5. 关于XML文档的讲解

    1        XML的概述 1.1 什么是XML XML全称为Extensible Markup Language,意思是可扩展的标记语言.XML语法上和HTML比较相似,但HTML中的元素是固定 ...

  6. <你不知道的JavaScript>读书笔记

    近几天看了一本不错的 JavaScript 的书,是 Kyle Simpson 写的 <You Don't know JS>.这本书是 Kyle Simpson 在 Github 上的开源 ...

  7. 冒泡排序小实例 php

    源代码如下,仅用于参考: <?php$a = array(10,2,36,14,10,25,23,85,99,45); for($j=0;$j<9;$j++){ for($i=0;$i&l ...

  8. http协议与内容压缩

    为了加快网络上的传输的速度,可以将服务器传输的内容进行压缩,服务器的压缩方式有gzip压缩 deflate压缩 compress压缩 content-length:压缩后的长度 如何启动压缩功能 1, ...

  9. Cordova+angularjs+ionic+vs2015开发(一)

    欢迎加群学习:457351423 这里有4000多部学习视频,涵盖各种技术,有需要的欢迎进群学习! 一.Windows环境配置 1.如果已经安装VS2015,打开[工具]-[选项]找到Cordova选 ...

  10. c#调用JAVA的Webservice处理XML数据及批量轮询的实现方法

    前段时间做一个调用外单位WEBSERVICE的项目,项目完成的功能其实很简单,就是我们单位有很多车友会员,我们想对他们提供车辆违章信息告之服务!我们这边交警部门给我们开放了WS的接口,我们就是想通过这 ...