POJ 3693 Maximum repetition substring ——后缀数组
重复次数最多的字串,我们可以枚举循环节的长度。
然后正反两次LCP,然后发现如果长度%L有剩余的情况时,答案是在一个区间内的。
所以需要找到区间内最小的rk值。
两个后缀数组,四个ST表,$\Theta(n\log n)$
就可以解决了
空间卡死了,瞎晶胞卡过去了。
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define mp make_pair
#define maxn 200010
#define inf 0x3f3f3f3f int _log[maxn],kas=0; struct Suffix_Array{
int s[maxn];
int cnt[maxn],sa[maxn],tmp[maxn],rk[maxn],h[maxn];
int st[2][maxn][18];
void build(int n,int m)
{
s[n]=0; n++; int i,j,k;
F(i,0,n+2) sa[i]=tmp[i]=rk[i]=h[i]=0;
F(i,0,m-1) cnt[i]=0;
F(i,0,n-1) cnt[rk[i]=s[i]]++;
F(i,1,m-1) cnt[i]+=cnt[i-1];
F(i,0,n-1) sa[--cnt[rk[i]]]=i;
for (k=1;k<=n;k<<=1)
{
F(i,0,n-1)
{
int j=sa[i]-k;
if (j<0) j+=n;
tmp[cnt[rk[j]]++]=j;
}
sa[tmp[cnt[0]=0]]=j=0;
F(i,1,n-1)
{
if (rk[tmp[i]]!=rk[tmp[i-1]]||rk[tmp[i]+k]!=rk[tmp[i-1]+k]) cnt[++j]=i;
sa[tmp[i]]=j;
}
memcpy(rk,sa,n*sizeof(int));
memcpy(sa,tmp,n*sizeof(int));
if (j>=n-1) break;
}
for (int i=k=0;i<n;h[rk[i++]]=k)
for (k?k--:0,j=sa[rk[i]-1];s[i+k]==s[j+k];k++);
F(i,0,n-1) st[0][i][0]=h[i];
F(i,1,17) F(j,0,n-(1<<i)) st[0][j][i]=min(st[0][j][i-1],st[0][j+(1<<(i-1))][i-1]);
F(i,0,n-1) st[1][i][0]=rk[i];
F(i,1,17) F(j,0,n-(1<<i)) st[1][j][i]=min(st[1][j][i-1],st[1][j+(1<<(i-1))][i-1]);
}
int query(int id,int l,int r)
{
int k=_log[r-l+1];
return min(st[id][l][k],st[id][r-(1<<k)+1][k]);
}
int lcp(int a,int b)
{
int aa=rk[a],bb=rk[b];
return query(0,min(aa,bb)+1,max(aa,bb));
}
}SA,SB; int ansl,ansr,mx,ans,n,minn;char s[maxn]; void solve(int L)
{
for (int i=0;i+L<n;i+=L)
if (s[i]==s[i+L])
{
int l=SA.lcp(i+1,i+L+1),r=SB.lcp(n-i-1,n-i-L-1);
if (l+r<L) continue;
if ((l+r)/L+1>mx) mx=(l+r)/L+1,ans=inf;
if ((l+r)/L+1==mx)
{
int tmp=SA.query(1,i-r+1,i-r+1+(l+r)%L);
if (tmp<ans)
{
ans=tmp;
ansl=SA.sa[tmp]; ansr=ansl+mx*L-1;
}
}
}
} int main()
{
F(i,2,maxn-1) _log[i]=_log[i>>1]+1;
while (scanf("%s",s)!=EOF&&s[0]!='#')
{
ansl=ansr=0,mx=0;minn=inf;
printf("Case %d: ",++kas);
mx=0;
n=strlen(s);
F(i,0,n-1)
{
SA.s[i]=s[i]-'a'+1;
SB.s[i]=s[n-i-1]-'a'+1;
minn=min(minn,(int)s[i]);
}
SA.s[n]=SB.s[n]=0;
SA.build(n,30); SB.build(n,30);
for (int i=1;i<=n;++i) solve(i);
if (mx==0) printf("%c\n",minn);
else
{
F(i,ansl,ansr) printf("%c",s[i]);
printf("\n");
}
}
}
POJ 3693 Maximum repetition substring ——后缀数组的更多相关文章
- poj 3693 Maximum repetition substring (后缀数组)
其实是论文题.. 题意:求一个字符串中,能由单位串repeat得到的子串中,单位串重复次数最多的子串.若有多个重复次数相同的,输出字典序最小的那个. 解题思路:其实跟论文差不多,我看了很久没看懂,后来 ...
- POJ 3693 Maximum repetition substring (后缀数组+RMQ)
题意:给定一个字符串,求其中一个由循环子串构成且循环次数最多的一个子串,有多个就输出最小字典序的. 析:枚举循环串的长度ll,然后如果它出现了两次,那么它一定会覆盖s[0],s[ll],s[ll*2] ...
- POJ3693 Maximum repetition substring 后缀数组
POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- POJ 3693 Maximum repetition substring(最多重复次数的子串)
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10461 Ac ...
- Maximum repetition substring 后缀数组
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7578 Acc ...
- POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS Memory Li ...
- POJ 3693 Maximum repetition substring(后缀数组)
Description The repetition number of a string is defined as the maximum number R such that the strin ...
- POJ 3693 Maximum repetition substring(后缀数组+ST表)
[题目链接] poj.org/problem?id=3693 [题目大意] 求一个串重复次数最多的连续重复子串并输出,要求字典序最小. [题解] 考虑错位匹配,设重复部分长度为l,记s[i]和s[i+ ...
随机推荐
- PL/SQL学习笔记(二)
select * from protype;select * from product;---笛卡尔连接查询(交叉连接)select * from protype,product;select * f ...
- Oracle 存储过程调用语句
#oracle 存储过程调用语句declare v_custName varchar2(10); --客户姓名 v_num number; --订单分布天数 v_time number; --每日订单 ...
- Nodejs + Jshint自动化静态代码检查
1. 目的 提交代码前能够自动化静态代码检查,提高代码质量 2. 准备 1. Nodejs安装: 官方地址:http://nodejs.org/ 安装说明:根据电脑配置下载对应的版本进行 ...
- Codeforces Round #316 (Div. 2) D Tree Requests
官方题解是离线询问,dfs树形转线性,然后二分找区间. 还有一种比较好的做法是直接dfs,将当前访问这个结点u相关的询问之前的状态存起来,然后访问完以后利用异或开关性,得到这颗子树上的答案. 代码是学 ...
- MYSQL 注射精华
前言鄙人今天心血来潮突然想写篇文章,鄙人从来没写过文章,如果有错误的地方请多多指教.本文需要有基础的SQL语句知识才可以更好的理解.建议想学习的人多去了解一下SQL语句和编程语言,知己知彼才能百战百胜 ...
- iOS开发遇到的坑之一: 开发遇见如下错误:Undefined symbols for architecture arm64
博客处女作,写得不好望谅解! “for architecture arm64”就是说没有支持arm64,在Build settings里architecture相关的几项需要配置正确 在最近升级coc ...
- ios之UITextfield
//初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 13 ...
- linux中进程亲和性绑定
什么是绑核所谓绑核,其实就是设定某个进程/线程与某个CPU核的亲和力(affinity).设定以后,Linux调度器就会让这个进程/线程只在所绑定的核上面去运行.但并不是说该进程/线程就独占这个CPU ...
- Linux基础学习-Docker学习笔记
Docker安装 1 官方网站访问速度很慢,帮助文档 2 国内中文网站,帮助文档 [root@qdlinux ~]# yum remove docker \ docker-client \ docke ...
- python:mysql增量备份
模块:MySQLdb Crypto加密 ConfigParser加载配置 mydb.py #!/usr/bin/env python #coding=utf-8 import MySQLdb as m ...