[BZOJ3230]相似子串(后缀数组)
显然可以通过后缀数组快速找到询问的两个串分别是什么,然后正反各建一个后缀数组来求两个串的LCP和LCS即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=,inf=1e9;
char s[N];
ll ans,x,y;
int n,Q,lg[N];
struct P{ int x,y; }; struct SA{
ll sm[N];
char s[N];
int x[N],y[N],c[N],sa[N],rk[N],h[N],mn[N][]; bool Cmp(int a,int b,int l){ return a+l<=n && b+l<=n && y[a]==y[b] && y[a+l]==y[b+l]; } void build(int m){
rep(i,,m) c[i]=;
rep(i,,n) c[x[i]=s[i]-'a'+]++;
rep(i,,m) c[i]+=c[i-];
for (int i=n; i; i--) sa[c[x[i]]--]=i;
for (int k=,p=; p<n; k<<=,m=p){
p=;
rep(i,n-k+,n) y[++p]=i;
rep(i,,n) if (sa[i]>k) y[++p]=sa[i]-k;
rep(i,,m) c[i]=;
rep(i,,n) c[x[y[i]]]++;
rep(i,,m) c[i]+=c[i-];
for (int i=n; i; i--) sa[c[x[y[i]]]--]=y[i];
rep(i,,n) y[i]=x[i]; x[sa[p=]]=;
rep(i,,n) x[sa[i]]=Cmp(sa[i],sa[i-],k) ? p : ++p;
}
} void init(){
rep(i,,n) rk[sa[i]]=i;
int k=;
rep(i,,n){
for (int j=sa[rk[i]-]; i+k<=n && j+k<=n && s[i+k]==s[j+k]; k++);
h[rk[i]]=k; if (k) k--;
}
rep(i,,n) sm[i]=sm[i-]+n-sa[i]+-h[i],mn[i][]=h[i];
rep(j,,) rep(i,,n-(<<j)+) mn[i][j]=min(mn[i][j-],mn[i+(<<(j-))][j-]);
} int que(int l,int r){
if (l==r) return inf;
l++; int t=lg[r-l+]; return min(mn[l][t],mn[r-(<<t)+][t]);
} P get(ll k){
int L=,R=n; int ans1,ans2;
if (sm[n]<k) return (P){-,-};
while (L<=R){
int mid=(L+R)>>;
if (sm[mid]>=k) ans1=mid,ans2=n-sa[mid]+-(sm[mid]-k),R=mid-; else L=mid+;
}
return (P){ans1,ans2};
}
}S1,S2; int main(){
freopen("bzoj3230.in","r",stdin);
freopen("bzoj3230.out","w",stdout);
scanf("%d%d%s",&n,&Q,s+);
rep(i,,n) lg[i]=lg[i>>]+;
rep(i,,n) S1.s[i]=S2.s[n-i+]=s[i];
S1.build(); S2.build(); S1.init(); S2.init();
rep(i,,Q){
scanf("%lld%lld",&x,&y); ans=;
if (S1.sm[n]<y){ puts("-1"); continue; }
P xx=S1.get(x),yy=S1.get(y);
ll k=min(S1.que(xx.x,yy.x),min(xx.y,yy.y)); ans+=k*k;
xx.x=S2.rk[n-S1.sa[xx.x]+-xx.y]; yy.x=S2.rk[n-S1.sa[yy.x]+-yy.y];
k=min(S2.que(min(xx.x,yy.x),max(xx.x,yy.x)),min(xx.y,yy.y)); ans+=k*k;
printf("%lld\n",ans);
}
return ;
}
[BZOJ3230]相似子串(后缀数组)的更多相关文章
- BZOJ3230 相似子串[后缀数组+二分+st表]
BZOJ3230 相似子串 给一个串,查询排名i和j的子串longest common suffix和longest common prefix 思路其实还是蛮好想的,就是码起来有点恶心.可以发现后缀 ...
- poj 2774 最长公共子串 后缀数组
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 25752 Accepted: 10 ...
- URAL 1297 最长回文子串(后缀数组)
1297. Palindrome Time limit: 1.0 secondMemory limit: 64 MB The “U.S. Robots” HQ has just received a ...
- poj 1743 Musical Theme(最长重复子串 后缀数组)
poj 1743 Musical Theme(最长重复子串 后缀数组) 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复 ...
- Cogs 1709. [SPOJ705]不同的子串 后缀数组
题目:http://cojs.tk/cogs/problem/problem.php?pid=1709 1709. [SPOJ705]不同的子串 ★★ 输入文件:subst1.in 输出文件: ...
- BZOJ 1396: 识别子串( 后缀数组 + 线段树 )
这道题各位大神好像都是用后缀自动机做的?.....蒟蒻就秀秀智商写一写后缀数组解法..... 求出Height数组后, 我们枚举每一位当做子串的开头. 如上图(x, y是height值), Heigh ...
- BZOJ 3230 相似子串 | 后缀数组 二分 ST表
BZOJ 3230 相似子串 题面 题解 首先我们要知道询问的两个子串的位置. 先正常跑一遍后缀数组并求出height数组. 对于每一个后缀suffix(i),考虑以i开头的子串有多少是之前没有出现过 ...
- bzoj 3230 相似子串——后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3230 作出后缀数组,从 LCP 看每个位置对于本质不同子串的贡献,而且他们已经按前面部分排好 ...
- 【poj1743-Musical Theme】不可重叠最长重复子串-后缀数组
http://poj.org/problem?id=1743 这题是一道后缀数组的经典例题:求不可重叠最长重复子串. 题意: 有N(1 <= N <=20000)个音符的序列来表示一首乐曲 ...
随机推荐
- Nginx服务器作反向代理实现内部局域网的url转发配置
情景 由于公司内网有多台服务器的http服务要映射到公司外网静态IP,如果用路由的端口映射来做,就只能一台内网服务器的80端口映射到外网80端口,其他服务器的80端口只能映射到外网的非80端口.非80 ...
- pyqt(day2)
一.安装python 二.安装pyqt5 pip install pyqt5 三.安装pycharm 四.第一个pyqt程序 import sys from PyQt5.QtWidgets impor ...
- FZU Monthly-201906 获奖名单
FZU Monthly-201906 获奖名单 冠军: 空缺 一等奖: 陈金杰 S031702334 空缺 二等奖: 黄海东 S031702647 吴宜航 S031702645 蔡煜晖 S111801 ...
- 在线生成安卓APP图标
移动应用图标/启动图生成工具,一键生成所有尺寸的应用图标/启动图 在线生成安卓APP图标生成 图标在 线 在线图标 安卓图标 生成图标 https://icon.wuruihong.com/ 在线pn ...
- Oracle 行转列 动态出转换的列
本文链接:https://blog.csdn.net/Huay_Li/article/details/82924443 10月的第二天,前天写了个Oracle中行转列的pivot的基本使用方法,然后, ...
- ubuntu18 任务栏调到底部
$ gsettings set org.gnome.shell.extensions.dash-to-dock dock-position BOTTOM 原因如下: https://askubuntu ...
- centos7 python2.7升级至python3.5.3版本
1.wget https://www.python.org/ftp/python/3.5.3/Python-3.5.3.tgz #下载安装包 2.tar -zxvf Python-3.5.3 ...
- SpringMVC 事件监听 ApplicationListener
1. 实现 ApplicationListener<T> 接口(T为监听类型,稍后会列出具体可监听事件) 2. 将该自定义监听类,注册为Spring容器组件.(即将该类注入Spring容器 ...
- Java学习-053-JSON工具类演示
日常开发工作,经常遇到使用JSON数据,好久没有写了,今晚抽了三个小时时间写了个JSON工具类,主要包含如下几个方法: 获取JSON字符串所有键路径列表: 获取JSON字符串所有键值列表: JSON数 ...
- 【PHP】使用phpoffice/phpspreadsheet导入导出数据
当你在使用phpoffice/phpexcel 类库时候.composer 会给你提示一句话 Package phpoffice/phpexcel is abandoned, you should a ...