【SPOJ687&POJ3693】Maximum repetition substring(后缀数组)
题意:
n<=1e5
思路:
From http://hzwer.com/6152.html
往后匹配多远 r 用ST表求lcp即可。。。往前 l 就把串反过来再做一下。。
但是有可能求出来的最长串可以前移/后移几位
即开头可以在落在[i−l,i−l+(l+r)mod L]
区间内字典序最小的还要用ST表找rank区间最值
有空需要学习一下结构体写法 一模一样的东西写多次太累了
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 110000
#define MOD 1000000007
#define eps 1e-8
#define pi acos(-1)
#define oo 1000000000 char ch[N];
int n,i,s[N],sa[N],wa[N],wb[N],wc[N],wd[N],height[N],rank[N],
ans,mx,ansl,ansr,f[][N][],g[][N],save[N],Log[N],bin[N]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} bool cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
} void getsa(int *r,int *sa,int n,int m)
{
int *x=wa,*y=wb,j,p;
for(i=;i<n;i++) wc[x[i]=r[i]]++;
for(i=;i<m;i++) wc[i]+=wc[i-];
for(i=n-;i>=;i--) sa[--wc[x[i]]]=i;
for(j=,p=;p<n;j*=,m=p)
{
p=;
for(i=n-j;i<n;i++) y[p++]=i;
for(i=;i<n;i++)
if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=;i<n;i++) wd[i]=x[y[i]];
for(i=;i<m;i++) wc[i]=;
for(i=;i<n;i++) wc[wd[i]]++;
for(i=;i<m;i++) wc[i]+=wc[i-];
for(i=n-;i>=;i--) sa[--wc[wd[i]]]=y[i];
swap(x,y);
p=; x[sa[]]=;
for(i=;i<n;i++) x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
} void getheight(int *r,int *sa,int n)
{
int i,j,k=;
for(i=;i<=n;i++) rank[sa[i]]=i;
for(i=;i<n;height[rank[i++]]=k)
{
if(k) k--;
j=sa[rank[i]-];
while(r[i+k]==r[j+k]) k++;
}
} void init()
{
memset(s,,sizeof(s));
memset(sa,,sizeof(sa));
memset(wa,,sizeof(wa));
memset(wb,,sizeof(wb));
memset(wc,,sizeof(wc));
memset(wd,,sizeof(wd));
memset(height,,sizeof(height));
memset(rank,,sizeof(rank));
} int lcp(int p,int x,int y)
{
int t;
int L=g[p][x];
int R=g[p][y];
if(L>R){t=L; L=R; R=t;}
L++;
int q=Log[R-L+];
return min(f[p][L][q],f[p][R-bin[q]+][q]);
} int query(int x,int y)
{
int q=Log[y-x+];
return min(f[][x][q],f[][y-bin[q]+][q]);
} void solve(int L)
{
for(int i=;i+L<n;i+=L)
if(ch[i]==ch[i+L])
{
int r=lcp(,i,i+L);
// printf("1 %d %d %d\n",i,i+L,r);
int l=lcp(,n-i,n-i-L);
// printf("2 %d %d %d\n",n-i,n-i-L,l);
if((l+r)/L+>mx) {mx=(l+r)/L+; ans=oo;}
if((l+r)/L+==mx)
{
int t=query(i-l,i-l+(l+r)%L);
// printf("%d %d %d\n",i-l,i-l+(l+r)%L,t);
if(t<ans)
{
ans=t;
ansl=save[t];
ansr=ansl+mx*L-;
}
}
}
} int main()
{
//freopen("poj3693.in","r",stdin);
//freopen("poj3693.out","w",stdout);
bin[]=;
for(int i=;i<;i++) bin[i]=bin[i-]<<;
Log[]=-;
for(int i=;i<=;i++) Log[i]=Log[i/]+;
int cas=;
while(scanf("%s",ch))
{
if(ch[]=='#') break;
cas++;
printf("Case %d: ",cas); init();
n=strlen(ch);
for(int i=;i<n;i++) s[i]=ch[i]-'a'+;
s[n]=;
getsa(s,sa,n+,);
getheight(s,sa,n); for(int i=;i<n;i++) f[][i][]=rank[i]; int len=Log[n];
for(int i=;i<=n;i++) f[][i][]=height[i];
for(int i=;i<=len;i++)
for(int j=;j+bin[i]-<=n;j++)
f[][j][i]=min(f[][j][i-],f[][j+bin[i-]][i-]);
for(int i=;i<=n;i++) g[][i]=rank[i];
for(int i=;i<=n;i++) save[i]=sa[i]; init();
for(int i=;i<n;i++) s[i]=ch[n--i]-'a'+;
s[n]=;
getsa(s,sa,n+,);
getheight(s,sa,n); for(int i=;i<=n;i++) f[][i][]=height[i];
for(int i=;i<=len;i++)
for(int j=;j+bin[i]-<=n;j++)
f[][j][i]=min(f[][j][i-],f[][j+bin[i-]][i-]);
for(int i=;i<=n;i++) g[][i]=rank[i]; for(int i=;i<=len;i++)
for(int j=;j+bin[i]-<=n-;j++)
f[][j][i]=min(f[][j][i-],f[][j+bin[i-]][i-]); ansl=ansr=;
mx=; ans=oo;
for(int i=;i<n;i++)
if(ch[i]<ch[ansl]){ans=; ansl=ansr=i;}
for(int i=;i<=n;i++) solve(i);
for(int i=ansl;i<=ansr;i++) printf("%c",ch[i]);
printf("\n");
}
return ;
}
【SPOJ687&POJ3693】Maximum repetition substring(后缀数组)的更多相关文章
- POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS Memory Li ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- POJ3693 Maximum repetition substring 后缀数组
POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...
- poj3693 Maximum repetition substring (后缀数组+rmq)
Description The repetition number of a string is defined as the maximum number R such that the strin ...
- Maximum repetition substring 后缀数组
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7578 Acc ...
- POJ 3693 Maximum repetition substring ——后缀数组
重复次数最多的字串,我们可以枚举循环节的长度. 然后正反两次LCP,然后发现如果长度%L有剩余的情况时,答案是在一个区间内的. 所以需要找到区间内最小的rk值. 两个后缀数组,四个ST表,$\Thet ...
- 【Poj-3693】Maximum repetition substring 后缀数组 连续重复子串
POJ - 3693 题意 SPOJ - REPEATS的进阶版,在这题的基础上输出字典序最小的重复字串. 思路 跟上题一样,先求出最长的重复次数,在求的过程中顺便纪录最多次数可能的长度. 因为sa数 ...
- poj 3693 Maximum repetition substring (后缀数组)
其实是论文题.. 题意:求一个字符串中,能由单位串repeat得到的子串中,单位串重复次数最多的子串.若有多个重复次数相同的,输出字典序最小的那个. 解题思路:其实跟论文差不多,我看了很久没看懂,后来 ...
- POJ 3693 Maximum repetition substring (后缀数组+RMQ)
题意:给定一个字符串,求其中一个由循环子串构成且循环次数最多的一个子串,有多个就输出最小字典序的. 析:枚举循环串的长度ll,然后如果它出现了两次,那么它一定会覆盖s[0],s[ll],s[ll*2] ...
- poj3693 Maximum repetition substring
题意 给出一个长度为\(n(n\leqslant 100000)\)的串,求一个字典序最小的子串使得它是某个字符串重复\(k\)次得到的,且\(k\)最大 题解 后缀数组论文上的题,跟上一篇uva那个 ...
随机推荐
- KTU Programming Camp (Winter Training Day 1)
A.B.C(By musashiheart) 0216个人赛前三道题解 E(By ggg) Gym - 100735E Restore H(by pipixia) Gym - 100735H
- 动态规划初步-单向STP
一.题目 给一个m行n列(m <= 10,n <= 100)的整数矩阵,从第一列任何位置出发每次往右.右下.右上走一格,最终达到最后一列.要求经过的整数之和最小.整个矩阵是环形的,即第一行 ...
- vue2.0动画
相对于vue1.0来说,vue2.0的动画变化还是挺大的, 在1.0中,直接在元素中加 transition ,后面跟上名字. 而在vue2.0中,需要把设置动画的元素.路由放在<transit ...
- OpenCV2:介绍
一.OpenCV简介 OpenCV所有的类和函数都在cv命名空间里面,可以用 using namespace cv; #include "opencv2/opencv.hpp" 1 ...
- Bootstrap 翻页(pager)
如果您想要创建一个简单的分页链接为用户提供导航,可以通过翻页来实现.与分布链接一样,也是一个无序列表.默认情况下,翻页是居中显示的.下面列出了bootstrap处理翻页的类. Class 描述 示例代 ...
- Linux网卡设置为网桥模式
Linux网卡设置为网桥模式 1. 添加网卡,并修改相关配置文件 1.1虚拟机添加网卡,并配置相关文件 如:eth2为新添加网卡 cd /etc/sysconfig/network-script ...
- (18)zabbix值映射Value mapping
1. 介绍 zabbix为了显示更人性化的数据,在使用过程中,我们可以将获取到得数据映射为一个字符串. 比如,我们写脚本监控MySQL是否在运行中, 一般返回0表示数据库挂了,1表示数据库正常,还有各 ...
- JavaWeb项目中集成Swagger API文档
1.增加依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-sw ...
- 我的Python分析成长之路10
matplot数据可视化基础 制作提供信息的可视化(有时称作绘图)是数据分析中最重要任务之一. 1.图片(画布)与子图 plt.figure :创建一张空白的图片,可以指定图片的大小.像素. figu ...
- PAT Basic 1050
1050 螺旋矩阵 本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”.所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充.要求矩阵的规模为 m 行 n 列,满足条件: ...