考虑到K很小,于是可以暴搜每次用的是哪种操作,跳过AB相等的字符可以用SA求LCP加速。

主要流程就是,枚举B的每个后缀,对每个后缀统计合法前缀个数。DFS搜索每次决策,用SA跳过相同字符,当A或B匹配到结尾时统计答案。

每次某个串匹配到结尾时,B中的某个区间的前缀都会合法,注意到这些合法的前缀长度与A长度相差一定不超过K,于是用一个2*K+1的差分数组记录答案即可。复杂度$O(n\log n+n3^K)$

 #include<cstring>
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=;
int K,m,na,nb,n,d,ans,lg[N],h[N],c[N],x[N],y[N],sa[N],rk[N],st[N][];
char s[N],A[N],B[N]; bool Cmp(int a,int b,int l){ return y[a]==y[b] && y[a+l]==y[b+l]; } void getSA(int m){
memset(y,,sizeof(y));
rep(i,,m) c[i]=;
rep(i,,n) c[x[i]=s[i]]++;
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]; p=; x[sa[]]=;
rep(i,,n) x[sa[i]]=Cmp(sa[i],sa[i-],k)?p:++p;
}
} void getH(){
rep(i,,n) rk[sa[i]]=i; int k=;
rep(i,,n){
for (int j=sa[rk[i]-]; j+k<=n && i+k<=n && s[i+k]==s[j+k]; k++);
h[rk[i]]=k; if (k) k--;
}
} void init(){
lg[]=; rep(i,,n) lg[i]=lg[i>>]+;
rep(i,,n) st[i][]=h[i];
rep(i,,) rep(j,,n-(<<i)+) st[j][i]=min(st[j][i-],st[j+(<<(i-))][i-]);
} int lcp(int l,int r){
int x=rk[l],y=rk[r+na+];
if (x>y) swap(x,y);
x++; int t=lg[y-x+];
return min(st[x][t],st[y-(<<t)+][t]);
} void col(int l,int r){ l=max(l,d); r=min(r,nb); c[K-(na-(l-d+))+]++; c[K-(na-(r-d+))+]--; } void dfs(int x,int y,int z){
int t=lcp(x,y); x+=t; y+=t;
if (x>na || y>nb){
int c=K-z-(na-x+);
if (c>=) col(y--c,y-+c);
return;
}
if (z==K) return;
dfs(x+,y,z+); dfs(x,y+,z+); dfs(x+,y+,z+);
} int main(){
freopen("bzoj4340.in","r",stdin);
freopen("bzoj4340.out","w",stdout);
scanf("%d%s%s",&K,A+,B+); m=*K+;
na=strlen(A+); nb=strlen(B+);
rep(i,,na) s[++n]=A[i]; s[++n]='#';
rep(i,,nb) s[++n]=B[i];
getSA(); getH(); init();
for (d=; d<=nb; d++){
rep(j,,m) c[j]=;
dfs(,d,);
rep(j,,m){
c[j]+=c[j-];
if (c[j]) ans++;
}
}
printf("%d\n",ans);
return ;
}

[BZOJ4340][BJOI2015]隐身术(后缀数组)的更多相关文章

  1. BZOJ4340:[BJOI2015]隐身术(后缀数组,ST表,DFS)

    Description 给定两个串A,B.请问B中有多少个非空子串和A的编辑距离不超过K? 所谓“子串”,指的是B中连续的一段.不同位置的内容相同的子串算作多个. 两个串之间的“编辑距离”指的是把一个 ...

  2. BZOJ.4340.[BJOI2015]隐身术(后缀数组 搜索)

    BZOJ \(Description\) 给定两个串\(S,T\)以及一个数\(k\),求\(T\)中有多少个子串,满足和\(S\)的编辑距离不超过\(k\). \(|S|+|T|\leq10^5,\ ...

  3. BZOJ4340 : BJOI2015 隐身术

    枚举$B$串的每个后缀,统计出该后缀所有满足条件的前缀. 考虑暴力搜索,设状态$(x,y,z)$表示当前需要考虑$A$从$x$开始的后缀,$B$从$y$开始的后缀,之前部分编辑距离为$z$. 那么首先 ...

  4. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

  5. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  6. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

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

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

  8. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  9. 后缀数组(suffix array)详解

    写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...

随机推荐

  1. SDUT 3928

    Description C~K 和 PBH 经常玩一个游戏.游戏规则如下:现给定一个 n*n 的棋盘,一个石头被放在棋盘的左上角. 他们轮流移动石头.每一回合,两个人只能把石头向上,下,左,右四个方向 ...

  2. 【转】E: Sub-process /usr/bin/dpkg returned an error code (1)

    原链接: jaryWang:E: Sub-process /usr/bin/dpkg returned an error code (1)错误解决 1.$ sudo mv /var/lib/dpkg/ ...

  3. js-打地鼠游戏开发

    [生成画布] 第1课[随机生成地鼠] 第2课[定时生成地鼠] 第3课[打地鼠完结篇] 第4课 优酷在线播放地址 http://list.youku.com/albumlist/show?id=2939 ...

  4. WordPress友情链接插件的安装

    插件:link manager 这样就安装成功! 在外观小工具里 把右边即可 这样在前台页面上就可看见添加的友情链接了!!!

  5. iOS中UITabelView

    1.概述 继承自UIScrollView,只能显示一列数据,只能纵向滑动.堪称UIKit里面最复杂的一个控件了,使用起来不算难,但是要用好并不容易.当使用的时候我们必须要考虑到后台数据的设计,tabl ...

  6. app 测试基础

    1. 安装和启动 (1) OTA安装测试 ·         app必须能够通过ota安装到测试设备上 ·         如果app安装完后没有icon,那么必须能够通过其他的方法来启动这个app ...

  7. 在Ubuntu上安装搜狗输入法

    1.进入搜狗输入法官网 2.下载Linux版本,选择64bit 下载 3.等待下载的同时,进行系统配置 进入系统设置->语言支持->进行更新(需要输入登录密码)->在键盘输入法系统选 ...

  8. word2vec原理

    最原始的是NNLM,然后对其改进,有了后面的层次softmax和skip gram 层次softmax:去掉了隐藏层,后面加了huffuman树,concat的映射层也变成了sum skip gram ...

  9. 关于真多核和加多核&线程由哪几部分组成

    网上查的资料小结,没有考证. 真多核是指一个cpu多个核心,即多个内核. 假多核是指多个cpu捆绑形成的分布式计算,ARM针对服务器市场推出的处理器为多个cpu的 真多核的应用奔腾和因特尔 双核芯cp ...

  10. ultra-console

    console.__proto__.styleText = function (option) { if (!option) { console.groupCollapsed('请输入option') ...