题意:

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(后缀数组)的更多相关文章

  1. POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串

    题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS   Memory Li ...

  2. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  3. POJ3693 Maximum repetition substring 后缀数组

    POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...

  4. poj3693 Maximum repetition substring (后缀数组+rmq)

    Description The repetition number of a string is defined as the maximum number R such that the strin ...

  5. Maximum repetition substring 后缀数组

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7578   Acc ...

  6. POJ 3693 Maximum repetition substring ——后缀数组

    重复次数最多的字串,我们可以枚举循环节的长度. 然后正反两次LCP,然后发现如果长度%L有剩余的情况时,答案是在一个区间内的. 所以需要找到区间内最小的rk值. 两个后缀数组,四个ST表,$\Thet ...

  7. 【Poj-3693】Maximum repetition substring 后缀数组 连续重复子串

    POJ - 3693 题意 SPOJ - REPEATS的进阶版,在这题的基础上输出字典序最小的重复字串. 思路 跟上题一样,先求出最长的重复次数,在求的过程中顺便纪录最多次数可能的长度. 因为sa数 ...

  8. poj 3693 Maximum repetition substring (后缀数组)

    其实是论文题.. 题意:求一个字符串中,能由单位串repeat得到的子串中,单位串重复次数最多的子串.若有多个重复次数相同的,输出字典序最小的那个. 解题思路:其实跟论文差不多,我看了很久没看懂,后来 ...

  9. POJ 3693 Maximum repetition substring (后缀数组+RMQ)

    题意:给定一个字符串,求其中一个由循环子串构成且循环次数最多的一个子串,有多个就输出最小字典序的. 析:枚举循环串的长度ll,然后如果它出现了两次,那么它一定会覆盖s[0],s[ll],s[ll*2] ...

  10. poj3693 Maximum repetition substring

    题意 给出一个长度为\(n(n\leqslant 100000)\)的串,求一个字典序最小的子串使得它是某个字符串重复\(k\)次得到的,且\(k\)最大 题解 后缀数组论文上的题,跟上一篇uva那个 ...

随机推荐

  1. 如何计算CDS view里两个时间戳之间的天数间隔

    ABAP透明表里的时间戳,数据类型为dec: 有个需求:计算这两个时间戳之间的天数间隔,丢弃时间戳年-月-日8位后面的小时:分钟:秒. 举个例子:如果时间戳是20180918173132,丢弃1731 ...

  2. Lesson1

    #ifdef __cplusplus #include <cstdlib> #else #include <stdlib.h> #endif #include <SDL/ ...

  3. windows中安装模拟器后修改模拟器中的hosts方法

    1.背景 有的时候我们测试安卓的app需要绑定hosts,这个时候我们如果只是修改PC机器上的hosts,然而在模拟器中并不生效.这个时候我们就需要修改模拟器中的hosts. 模拟器中的hosts为只 ...

  4. 手把手教你写 Vue UI 组件库

    最近在研究 muse-ui 的实现,发现网上很少有关于 vue 插件具体实现的文章,官方的文档也只是一笔带过,对于新手来说并不算友好. 笔者结合官方文档,与自己的摸索总结,以最简单的 FlexBox  ...

  5. atom 自定义快捷键

    'atom-text-editor': 'shift-alt-i':'core:move-up' 'shift-alt-space':'core:move-down' 'shift-alt-l':'c ...

  6. Pacman常用命令 文内搜索吧

    列出已经安装的软件包 https://wiki.archlinux.org/index.php/Pacman_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)  维基 pa ...

  7. Paxos算法与Zookeeper分析,zab (zk)raft协议(etcd) 8. 与Galera及MySQL Group replication的比较

    mit 分布式论文集 https://github.com/feixiao/Distributed-Systems wiki上描述的几种都明白了就出师了 raft 和 zab 是类似的,都是1.先选举 ...

  8. ClientAbortException:java.io.IOException解决方案

    org.apache.catalina.connector Class ClientAbortException java.lang.Object java.lang.Throwable java.l ...

  9. 【STL】栈+队列+优先队列(详)+ 拯救行动题解

    一.栈 栈(stack)又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈,它是把新元 ...

  10. Python基础知识-day2

    格式化输出 %占位符,s字符串,d 数字, 表示%  用%% name = input("请输入姓名: ") age = input("请输入年龄: ") he ...