SPOJ - REPEATS RMQ循环节
题意:求重复次数最多的重复子串(并非长度最长)
枚举循环子串长度\(L\),求最多能连续出现多少次,相邻的节点往后的判断可以使用\(LCP\)得到值为\(K\),那么得到一个可能的解就是\(K/L+1\)
这个不是最优解,还需要往前判断,往前的判断必须是两个后缀依然等间距的,而且首个后缀必须在此前已经枚举过的后缀之后(否则无意义),并且最优情况只会比上述\(K/L+1\)大1
翻别人题解找到一个很简洁的式子,可以很轻易的凑出\(L\)的整数倍的判断点(就是个补全),感觉有点像KMP啊
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iin(a) scanf("%d",&a)
#define lin(a) scanf("%lld",&a)
#define din(a) scanf("%lf",&a)
#define s0(a) scanf("%s",a)
#define s1(a) scanf("%s",a+1)
#define print(a) printf("%lld",(ll)a)
#define enter putchar('\n')
#define blank putchar(' ')
#define println(a) printf("%lld\n",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int maxn = 1e5+11;
const int oo = 0x3f3f3f3f;
const double eps = 1e-7;
typedef long long ll;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
char str[maxn];int n;
struct SA{
int Rank[maxn],sa[maxn],tsa[maxn],A[maxn],B[maxn];
int cntA[maxn],cntB[maxn];
int height[maxn],best[maxn][22],n;
void get(int nn){
n=nn;
rep(i,0,666) cntA[i]=0;
rep(i,1,n) cntA[str[i]]++;
rep(i,1,666) cntA[i]+=cntA[i-1];
rrep(i,n,1) sa[cntA[str[i]]--]=i;
Rank[sa[1]]=1;
rep(i,2,n){
if(str[sa[i]]==str[sa[i-1]]){
Rank[sa[i]]=Rank[sa[i-1]];
}else{
Rank[sa[i]]=1+Rank[sa[i-1]];
}
}
for(int l=1;Rank[sa[n]]<n;l<<=1){
rep(i,1,n) cntA[i]=cntB[i]=0;
rep(i,1,n) cntA[A[i]=Rank[i]]++;
rep(i,1,n) cntB[B[i]=(i+l<=n?Rank[i+l]:0)]++;
rep(i,1,n) cntA[i]+=cntA[i-1],cntB[i]+=cntB[i-1];
rrep(i,n,1) tsa[cntB[B[i]]--]=i;
rrep(i,n,1) sa[cntA[A[tsa[i]]]--]=tsa[i];
Rank[sa[1]]=1;
rep(i,2,n){
bool flag=A[sa[i]]==A[sa[i-1]]&&B[sa[i]]==B[sa[i-1]];
flag=!flag;
Rank[sa[i]]=Rank[sa[i-1]]+flag;
}
}
}
void ht(){
int j=0;
rep(i,1,n){
if(j) j--;
while(str[i+j]==str[sa[Rank[i]-1]+j]) j++;
height[Rank[i]]=j;
}
}
void rmq(){
rep(i,1,n) best[i][0]=height[i];
for(int i=1;(1<<i)<=n;i++){
for(int j=1;j+(1<<i)-1<=n;j++){
best[j][i]=min(best[j][i-1],best[j+(1<<(i-1))][i-1]);
}
}
}
int lcp(int l,int r){
if(l==r)return -oo;
if(l>r)swap(l,r);
l++;
int k=log(1.0*r-l+1)/log(2.0);
return min(best[l][k],best[r-(1<<k)+1][k]);
}
}sa;
int main(){
int kase=0,T=read();
while(T--){
n=read();
char tt[66];
rep(i,1,n){
s1(tt);
str[i]=tt[1];
}
sa.get(n);
sa.ht();
sa.rmq();
int ans=1;
for(int L=1;L<=n;L++){//L!=2
for(int i=1;i+L<=n;i+=L){
int K=sa.lcp(sa.Rank[i],sa.Rank[i+L]);
int t=K/L+1;
int pos=i-(L-K%L);
if(pos>=1&&sa.lcp(sa.Rank[pos],sa.Rank[pos+L])/L+1>t)t++;
ans=max(ans,t);
}
}
println(ans);
}
return 0;
}
SPOJ - REPEATS RMQ循环节的更多相关文章
- POJ - 2406 ~SPOJ - REPEATS~POJ - 3693 后缀数组求解重复字串问题
POJ - 2406 题意: 给出一个字符串,要把它写成(x)n的形式,问n的最大值. 这题是求整个串的重复次数,不是重复最多次数的字串 这题很容易想到用KMP求最小循环节就没了,但是后缀数组也能写 ...
- 【SPOJ – REPEATS】 后缀数组【连续重复子串】
字体颜色如何 字体颜色 SPOJ - REPEATS 题意 给出一个字符串,求重复次数最多的连续重复子串. 题解 引自论文-后缀数组--处理字符串的有力工具. 解释参考博客 "S肯定包括了字 ...
- UVA 10692 Huge Mods(指数循环节)
指数循环节,由于a ^x = a ^(x % m + phi(m)) (mod m)仅在x >= phi(m)时成立,故应注意要判断 //by:Gavin http://www.cnblogs. ...
- 【POJ 2406】Power Strings(KMP循环节)
终于靠着理解写出KMP了,两种KMP要代码中这种才能求循环节.i-next[i]就是循环节. #include<cstdio> #define N 1000005 char s[N]; i ...
- HNU 12869 Sequence(循环节)
题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=12869 解题报告:看到n的范围这么大,一看就是找规律,把前30 ...
- Codeforces Round #383 (Div. 2) A,B,C,D 循环节,标记,暴力,并查集+分组背包
A. Arpa’s hard exam and Mehrdad’s naive cheat time limit per test 1 second memory limit per test 256 ...
- 51Node 1035----最长的循环节
51Node 1035----最长的循环节 正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数. 1/6= 0.1 ...
- POJ 2185 Milking Grid KMP(矩阵循环节)
Milking Grid Time Limit: 3000MS Memory Lim ...
- KMP模板,最小循环节
(可以转载,但请注明出处!) 下面是有关学习KMP的参考网站 http://blog.csdn.net/yaochunnian/article/details/7059486 http://blog. ...
随机推荐
- Docker安装和使用Tomcat
1.搜索Tomcat镜像 docker search tomcat 2.下载Tomcat官方镜像 docker p ...
- POI技术
1.excel左上角有绿色小图标说明单元格格式不匹配 2.模板中设置自动计算没效果,需要加上sheet.setForceFormulaRecalculation(true); FileInputStr ...
- MSGPACK和PROTOBUF的故事(MSGPACK明显生产力不足)
作者曾经在2014年测试出MSGPACK的关键字和中文字符有很大的冲突,所以后来放弃了,本文为很多年前写的一个对比,后来我们一直在使用HTTP协议和PROTOBUF. 看看MSGPACK的文档,自称效 ...
- hadoop2.2分布式环境搭建
hadoop2.2的分布式环境需要配置的参数更多.但是需要安装的系统软件和单节点环境是一样的. 运行hadoop在非安全环境 hadoop的配置文件有两类: 1:只读的默认配置文件: core-def ...
- JQuery解决事件动画重复问题
开发项目时,经常要写动画效果,有时候会遇到动画重复问题,例如:当鼠标移动到某个元素上时,执行某个动画,当我鼠标多次移动到该元素时,该动画就要连续执行,那么怎么去解决呢? 话不多说,直接添代码,简单明了 ...
- 如何创建JUnit
这里拿Dynamic项目来演示,首先创建一个Dynamic项目,起名,点next, 继续点next, 将web.xml文件勾选,finish, 接下来在Java Resources->src下创 ...
- 关于modelsim闪退问题
电脑之前做过仿真,modelsim是可以完美调用的,但是最近莫名其妙的就出现闪退问题,不通过quartus或者ise调用,单独使用的时候也会闪退. 偶尔一次能抓到错误消息.如下图所示: 然并卵,网上根 ...
- Tomcat之——内存溢出设置JAVA_OPTS
答案1设置Tomcat启动的初始内存其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4.可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置三.实例,以下 ...
- android 多点触控
多点触控 1.多点触控从字面意思讲就是你用大于等于2根的手指触摸子啊手机屏幕上. Android中监听触摸事件是onTouchEvent方法,它的参数为MotionEvent,下面列举MotionEv ...
- libcurl坑
code = curl_easy_setopt(conn, CURLOPT_URL, ca.strUrl.c_str()); 要char* 不能string