题意:

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. CPP-基础:友元

    友元可以是一个函数,该函数被称为友元函数:友元也可以是一个类,该类被称为友元类. 我们已知道类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成 ...

  2. 14.list列表

    1).列表的切片 li = ['德玛西亚',[1,2,3],'luokesasi','eson','女神','jingdongi'] l1 = li[0] print(l1) #>>> ...

  3. please upgrade your plan to create a new private reposiory

    请升级你的计划来创建一个新的私人仓库 提交仓库到github,要公开,除非买他们服务,所以把勾去掉就好了keep this code private

  4. Java中的日期(Calendar、Date)

    (1)获取当前日期: java.util.Calendar calendar = java.util.Calendar.getInstance(); 或  = new java.util.Gregor ...

  5. Python学习笔记2(序列)

    元组不可变序列 tuple函数 总结 字符串 基本字符串的操作 字符串格式化 字符串方法 find join lower replace split strip translate 小结 元组:不可变 ...

  6. HDU-2018-奶牛的故事

    这题找到递推式就好写了,递推式大致是: f=n (n<=4) f=f(n-1)+f(n-3) (n>4) 其实这题的题意,我觉得是有很大的问题的,它前后说的每年年初的意思都不一样,敬请参考 ...

  7. mysqlfailover测试

    mysqlfailover是mysql官方用python语言写的一款工具,包含在mysql utilities工具集中.主要作用是保障mysql高可用.他会定时检测节点状态,当master节点不可用时 ...

  8. C语言实现链表及其操作

    #include <stdio.h> #include <stdlib.h> //定义节点 typedef struct Node { int data; struct Nod ...

  9. ajax实现上传图片保存到后台并读取

    上传图片有两种方式: 1.fileReader  可以把图片解析成base64码的格式,简单粗暴 2.canvas  可以重新绘制一张图片,可以先把获取得到的图片的blob放进canvas里面,再生成 ...

  10. python爬虫基础03-requests库

    优雅到骨子里的Requests 本文地址:https://www.jianshu.com/p/678489e022c8 简介 上一篇文章介绍了Python的网络请求库urllib和urllib3的使用 ...