考虑到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. 【BZOJ】1951[Sdoi2010]古代猪文

    [题意]给定G,N,求: $$ans=G^{\sum_{i|n}\binom{n}{i}}\ \mod\ \ p$$ 1<=N,G<=10^9,p=999911659. [算法]欧拉定理+ ...

  2. 【CodeForces】908 E. New Year and Entity Enumeration

    [题目]E. New Year and Entity Enumeration [题意]给定集合T包含n个m长二进制数,要求包含集合T且满足以下条件的集合S数:长度<=m,非和与的结果都在集合中. ...

  3. 自定义 feign 反序列化时间字符格式

    参考 : https://blog.csdn.net/forezp/article/details/73480304 feign client 默认配置类:默认的配置类为FeignClientsCon ...

  4. Tomcat 调优及 JVM 参数优化

    Tomcat 本身与 JVM 优化 Tomcat:调整Server.xml JVM:bat启动服务方式的话修改catalina.bat 服务式启动的话参考:http://www.cnblogs.com ...

  5. perl6正则 3: 行开头与结尾与多行开头,多行结尾

    ^ $ 匹配一行的开头或结尾, 可以用 ^ 或 $. > so 'abcde' ~~ /e$/ True > so 'abcdef' ~~ /e$/ False > so 'abcd ...

  6. docker之安装和基本使用(一)

    前言 开始折腾docker. 主要概念 容器:独立运行的一个或一组应用,与其他应用完全独立. 镜像:用于创建 Docker容器的模板. 仓库:用于收纳镜像文件,可以理解为代码控制中的代码仓库 注意: ...

  7. python之微信公众号开发(基本配置和校验)

    前言 最近有微信公众号开发的业务,以前没有用python做过微信公众号开发,记录一下自己的学习和开发历程,共勉! 公众号类型 订阅号 普通订阅号 认证订阅号 服务号 普通服务号 认证服务号 服务方式 ...

  8. 关于Hazard Pointers的话题

    关于Hazard Pointers的话题, 起源于这个文章: 实现无锁的栈与队列(4) http://www.cnblogs.com/catch/p/3176636.html 其实他的系列文章(3)之 ...

  9. OC学习篇之---类的延展

    来源:http://blog.csdn.net/jiangwei0910410003/article/details/41775603 前一篇文章我们介绍了类的类目概念和使用:http://blog. ...

  10. RF和adaboost

    通过对所有的决策树进行加总来预测新的数据(在分类时采用多数投票,在回归时采用平均).