后缀数组 hash求LCP BZOJ 4310: 跳蚤
后缀数组的题博客里没放进去过。。所以挖了一题写写 充实下博客 顺便留作板子。。
一个字符串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: 跳蚤的更多相关文章
- bzoj 4310 跳蚤 二分答案+后缀数组/后缀树
题目大意 给定\(k\)和长度\(\le10^5\)的串S 把串分成不超过\(k\)个子串,然后对于每个子串\(s\),他会从\(s\)的所有子串中选择字典序最大的那一个,并在选出来的\(k\)个子串 ...
- bzoj 4310: 跳蚤
Description 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典 ...
- ●BZOJ 4310 跳蚤
●赘述题目 给出一个字符串,要求分成k个子串,然后求出每个子串的字典序最大的子串(我称它为子子串),要使这k个子子串中的字典序最大的那个串(即魔力串)最小.输出该魔力串. (本题个人感觉很好,比较综合 ...
- HDU-4622 Reincarnation 后缀数组 | Hash,维护和,扫描
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给一个字符串,询问某字串的不同字串的个数. 可以用后缀数组来解决,复杂度O(n).先求出倍 ...
- FJUT3703 这还是一道数论题(二分 + hash + manacher 或者 STL + hash 或者 后缀数组 + hash)题解
Problem Description 最后来个字符串签个到吧,这题其实并不难,所需的算法比较基础,甚至你们最近还上过课. 为了降低难度,免得所有人爆零.这里给几个提示的关键字 :字符串,回文,二分, ...
- URAL - 1297 后缀数组的做法 LCP应用
题意:求最长回文子串 这种有专门的O(n)套板子算法,但作为练习还是用后缀数组来解吧 只需把相同的另一个串反接(中间用一个足够小且未出现的字符衔接),然后枚举回文串的中点,不断求解该点往前和往后计算的 ...
- Uva12206 Stammering Aliens 后缀数组&&Hash
Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all effort ...
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)(转)
永恒的大牛,kuangbin,膜拜一下,Orz 链接:http://www.cnblogs.com/kuangbin/archive/2013/04/23/3039313.html Musical T ...
- URAL 1297 后缀数组:求最长回文子串
思路:这题下午搞了然后一直WA,后面就看了Discuss,里面有个数组:ABCDEFDCBA,这个我输出ABCD,所以错了. 然后才知道自己写的后缀数组对这个回文子串有bug,然后就不知道怎么改了. ...
随机推荐
- Codeforces Round #387 (Div. 2) A+B+C+D!
A. Display Size 水题,暴力(数据都是水题).0:04 int main() { int n; while(~scanf("%d",&n)) { int mi ...
- 简单的Fleury算法模板
假设数据输入时采用如下的格式进行输入:首先输入顶点个数n和边数m,然后输入每条边,每条边的数据占一行,格式为:u,v,表示从顶点u到顶点v的一条有向边 这里把欧拉回路的路径输出了出来: 手写栈: #i ...
- [luoguP1273] 有线电视网(DP)
传送门 f[i][j]表示节点i选j个用户的最大收益 #include <cstdio> #include <cstring> #include <iostream> ...
- BZOJ1777: [Usaco2010 Hol]rocks 石头木头
n<=10000的树,节点有初始石头数<=1000,进行这样的游戏:两人轮流行动,我先手,每次可以选一个节点(≠1)把不超过m<=1000个石头移到父亲,最后所有石头都在节点1,没法 ...
- linux日志服务器审计客户端history记录
https://blog.csdn.net/yanggd1987/article/details/70255179
- $.post()用法例子
1:删除用户操作 $('.delete').click(function(){ var classid=$(this).parent().siblings().eq(0).children().val ...
- winServer-常用winrm命令
学习WinServer必须学习powershell,学习powershell必须掌握远程管理服务器的方法,所以必须学会winrm来远程管理服务器 记录一些常用的winrm命令和错误 常用命令 //在P ...
- 洛谷 P3811 【模板】乘法逆元
P3811 [模板]乘法逆元 题目背景 这是一道模板题 题目描述 给定n,p求1~n中所有整数在模p意义下的乘法逆元. 输入输出格式 输入格式: 一行n,p 输出格式: n行,第i行表示i在模p意义下 ...
- ios开发 MPMoviePlayerController 视频播放器
项目中用到视频播放功能, 写点视频基础部分 MPMoviePlayerController是通过MediaPlayer.frame引入的,可用于播放在iOS支持的所有格式的视频,用起来很简单!!! M ...
- CEF3研究(二)
应用程序结构 每个CEF3应用程序都有一个相同的结构: 提供一个入口函数以初始化CEF和运行每个子进程逻辑和CEF消息处理 提供一个CefApp子类处理某个进程的回调 提供一个CefClinet子类处 ...