后缀数组的题博客里没放进去过。。所以挖了一题写写 充实下博客 顺便留作板子。。

一个字符串S中 内容不同的子串 有 sigma{n-sa[i]+1-h[i]}   (噢 这里的h[]就是大家熟知的height[])

所以l=1,r=上述sigma 二分 答案是字典序第几大的子串。

然后 求S中第k大的子串W : 因为h[i]是与i-1有关的 所以要从n downto 1,k-=n-sa[i]+1-h[i] 至 k再减就非正了

显然这样扫过来 子串字典序是递减的  因此可以得到第k大子串W

然后再贪心 n downto 1 若遇到比 W大的子串 就划分,验证 当前二分的这个第k大可不可行

判断 比W大还是小 用hash 二分求LCP即可

 #include <bits/stdc++.h>
#define N 200005
#define LL long long
using namespace std;
const LL mo=;
int F[],a[N],rank[N],sa[N],h[N],g1[N],g2[N],next[N],n,m,ans,k,t,l,r,mid,x,y,z;
char S[N]; LL f[N],w[N];
int oh(int k,int t,int p,int q){
int l=,r=min(t-k,q-p)+,j;
while (l<r){
j=l+r+>>;
(f[k+j-]-f[k-]*w[j]%mo+mo)%mo==(f[p+j-]-f[p-]*w[j]%mo+mo)%mo?
l=j:r=j-;
}
if (k+l>t) return ;
if (p+l>q) return ;
return a[k+l]>a[p+l];
}
int jud(int u){
int p,q,k,t;
for (int i=n;i;--i)
if (n-sa[i]+-h[i]<u) u-=n-sa[i]+-h[i];
else {p=sa[i];q=n-u+;break;}
t=n; k=;
for (int i=n;i;)
if (oh(i,t,p,q)){
if (i==t) return ;
t=i; ++k;
} else --i;
if (k>m) return ; return ;
}
int main(){
scanf("%d",&m); scanf("%s",S+); n=strlen(S+);
w[]=;
for (int i=;i<=n;++i) {
a[i]=S[i]-'a'+;
F[a[i]]=;
f[i]=(f[i-]*+a[i])%mo;
w[i]=w[i-]*%mo;
}
for (int i=;i<=;++i) F[i]+=F[i-];
for (int i=;i<=n;++i) rank[i]=F[a[i]]; t=F[];
for (int m=;m<n;m<<=){
for (int i=;i<=n;++i){
next[i]=g1[rank[i+m]];
g1[rank[i+m]]=i;
}
for (int i=t;i>=;--i){
for (int j=g1[i];j;j=k){
k=next[j]; next[j]=g2[rank[j]]; g2[rank[j]]=j;
}
g1[i]=;
}
z=;
for (int i=;i<=t;++i){
y=-;
for (int j=g2[i];j;j=k){
k=next[j]; next[j]=;
if (y!=rank[j+m]) y=rank[j+m],++z;
h[j]=z;
}
g2[i]=;
}
t=z;
for (int i=;i<=n;++i) rank[i]=h[i];
}
for (int i=;i<=n;++i) sa[rank[i]]=i,h[i]=;
for (int i=,k=;i<=n;++i)
if (rank[i]!=){
if (k) --k;
while (a[i+k]==a[sa[rank[i]-]+k]) ++k;
h[rank[i]]=k; r+=n-i+-k;
}
l=; ++r;
while (l<r){
k=l+r+>>;
jud(k)?l=k:r=k-;
}
for (int i=n;i;--i)
if (n-sa[i]+-h[i]<l) l-=n-sa[i]+-h[i];
else {k=sa[i];t=n-l+;break;}
for (int i=k;i<=t;++i) printf("%c",a[i]+'a'-);
return ;
}

Assassin

后缀数组 hash求LCP BZOJ 4310: 跳蚤的更多相关文章

  1. bzoj 4310 跳蚤 二分答案+后缀数组/后缀树

    题目大意 给定\(k\)和长度\(\le10^5\)的串S 把串分成不超过\(k\)个子串,然后对于每个子串\(s\),他会从\(s\)的所有子串中选择字典序最大的那一个,并在选出来的\(k\)个子串 ...

  2. bzoj 4310: 跳蚤

    Description 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典 ...

  3. ●BZOJ 4310 跳蚤

    ●赘述题目 给出一个字符串,要求分成k个子串,然后求出每个子串的字典序最大的子串(我称它为子子串),要使这k个子子串中的字典序最大的那个串(即魔力串)最小.输出该魔力串. (本题个人感觉很好,比较综合 ...

  4. HDU-4622 Reincarnation 后缀数组 | Hash,维护和,扫描

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给一个字符串,询问某字串的不同字串的个数. 可以用后缀数组来解决,复杂度O(n).先求出倍 ...

  5. FJUT3703 这还是一道数论题(二分 + hash + manacher 或者 STL + hash 或者 后缀数组 + hash)题解

    Problem Description 最后来个字符串签个到吧,这题其实并不难,所需的算法比较基础,甚至你们最近还上过课. 为了降低难度,免得所有人爆零.这里给几个提示的关键字 :字符串,回文,二分, ...

  6. URAL - 1297 后缀数组的做法 LCP应用

    题意:求最长回文子串 这种有专门的O(n)套板子算法,但作为练习还是用后缀数组来解吧 只需把相同的另一个串反接(中间用一个足够小且未出现的字符衔接),然后枚举回文串的中点,不断求解该点往前和往后计算的 ...

  7. Uva12206 Stammering Aliens 后缀数组&&Hash

    Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all effort ...

  8. POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)(转)

    永恒的大牛,kuangbin,膜拜一下,Orz 链接:http://www.cnblogs.com/kuangbin/archive/2013/04/23/3039313.html Musical T ...

  9. URAL 1297 后缀数组:求最长回文子串

    思路:这题下午搞了然后一直WA,后面就看了Discuss,里面有个数组:ABCDEFDCBA,这个我输出ABCD,所以错了. 然后才知道自己写的后缀数组对这个回文子串有bug,然后就不知道怎么改了. ...

随机推荐

  1. Codeforces Round #387 (Div. 2) A+B+C+D!

    A. Display Size 水题,暴力(数据都是水题).0:04 int main() { int n; while(~scanf("%d",&n)) { int mi ...

  2. 简单的Fleury算法模板

    假设数据输入时采用如下的格式进行输入:首先输入顶点个数n和边数m,然后输入每条边,每条边的数据占一行,格式为:u,v,表示从顶点u到顶点v的一条有向边 这里把欧拉回路的路径输出了出来: 手写栈: #i ...

  3. [luoguP1273] 有线电视网(DP)

    传送门 f[i][j]表示节点i选j个用户的最大收益 #include <cstdio> #include <cstring> #include <iostream> ...

  4. BZOJ1777: [Usaco2010 Hol]rocks 石头木头

    n<=10000的树,节点有初始石头数<=1000,进行这样的游戏:两人轮流行动,我先手,每次可以选一个节点(≠1)把不超过m<=1000个石头移到父亲,最后所有石头都在节点1,没法 ...

  5. linux日志服务器审计客户端history记录

    https://blog.csdn.net/yanggd1987/article/details/70255179

  6. $.post()用法例子

    1:删除用户操作 $('.delete').click(function(){ var classid=$(this).parent().siblings().eq(0).children().val ...

  7. winServer-常用winrm命令

    学习WinServer必须学习powershell,学习powershell必须掌握远程管理服务器的方法,所以必须学会winrm来远程管理服务器 记录一些常用的winrm命令和错误 常用命令 //在P ...

  8. 洛谷 P3811 【模板】乘法逆元

    P3811 [模板]乘法逆元 题目背景 这是一道模板题 题目描述 给定n,p求1~n中所有整数在模p意义下的乘法逆元. 输入输出格式 输入格式: 一行n,p 输出格式: n行,第i行表示i在模p意义下 ...

  9. ios开发 MPMoviePlayerController 视频播放器

    项目中用到视频播放功能, 写点视频基础部分 MPMoviePlayerController是通过MediaPlayer.frame引入的,可用于播放在iOS支持的所有格式的视频,用起来很简单!!! M ...

  10. CEF3研究(二)

    应用程序结构 每个CEF3应用程序都有一个相同的结构: 提供一个入口函数以初始化CEF和运行每个子进程逻辑和CEF消息处理 提供一个CefApp子类处理某个进程的回调 提供一个CefClinet子类处 ...