枚举$B$串的每个后缀,统计出该后缀所有满足条件的前缀。

考虑暴力搜索,设状态$(x,y,z)$表示当前需要考虑$A$从$x$开始的后缀,$B$从$y$开始的后缀,之前部分编辑距离为$z$。

那么首先用后缀数组+ST表求出两个后缀的lcp,$x$和$y$都可以向右跳那么多,且不产生任何代价。

如果此时匹配到了底,那么可以得到在一段区间$[L,R]$内,所有前缀都是合法的。注意到这种前缀只有$2K+1$种,所以可以使用差分前缀和来进行标记。

如果还没有匹配到底,那么有$3$种选择,分别是状态$(x+1,y,z+1)$、$(x,y+1,z+1)$以及$(x+1,y+1,z+1)$。

时间复杂度$O(n\log n+n3^k)$。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100010
using namespace std;
char s[N],A[N],B[N];
int K,na,nb,n,m,i,j,rk[N],sa[N],height[N],tmp[N],cnt[N],Log[N],f[17][N],c[15],ans;
void suffixarray(int n,int m){
int i,j,k;n++;
for(i=0;i<n;i++)cnt[rk[i]=s[i]]++;
for(i=1;i<m;i++)cnt[i]+=cnt[i-1];
for(i=0;i<n;i++)sa[--cnt[rk[i]]]=i;
for(k=1;k<=n;k<<=1){
for(i=0;i<n;i++){
j=sa[i]-k;
if(j<0)j+=n;
tmp[cnt[rk[j]]++]=j;
}
sa[tmp[cnt[0]=0]]=j=0;
for(i=1;i<n;i++){
if(rk[tmp[i]]!=rk[tmp[i-1]]||rk[tmp[i]+k]!=rk[tmp[i-1]+k])cnt[++j]=i;
sa[tmp[i]]=j;
}
memcpy(rk,sa,n*sizeof(int));
memcpy(sa,tmp,n*sizeof(int));
if(j>=n-1)break;
}
for(j=rk[height[i=k=0]=0];i<n-1;i++,k++)
while(~k&&s[i]!=s[sa[j-1]+k])height[j]=k--,j=rk[sa[j]+1];
}
inline int ask(int x,int y){
int k=Log[y-x+1];
return min(f[k][x],f[k][y-(1<<k)+1]);
}
inline int lcp(int x,int y){
if(x>=na||y>=nb)return 0;
x=rk[x],y=rk[y+na+1];
if(x>y)swap(x,y);
return ask(x+1,y);
}
inline void col(int l,int r){
if(l<i)l=i;
if(r>=nb)r=nb-1;
c[l-i-na+K+2]++,c[r-i-na+K+3]--;
}
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>=0)col(y-1-c,y-1+c);
return;
}
if(z==K)return;
z++;
dfs(x+1,y,z);
dfs(x,y+1,z);
dfs(x+1,y+1,z);
}
int main(){
scanf("%d%s%s",&K,A,B);
na=strlen(A),nb=strlen(B);
for(i=0;i<na;i++)s[n++]=A[i];
s[n++]='#';
for(i=0;i<nb;i++)s[n++]=B[i];
suffixarray(n,128);
for(i=2;i<=n;i++)Log[i]=Log[i>>1]+1;
for(i=1;i<=n;i++)f[0][i]=height[i];
for(j=1;j<17;j++)for(i=1;i+(1<<j-1)<=n;i++)f[j][i]=min(f[j-1][i],f[j-1][i+(1<<j-1)]);
for(m=2*K+1,i=0;i<nb;i++){
for(j=1;j<=m;j++)c[j]=0;
dfs(0,i,0);
for(j=1;j<=m;j++)if(c[j]+=c[j-1])ans++;
}
return printf("%d",ans),0;
}

  

BZOJ4340 : BJOI2015 隐身术的更多相关文章

  1. [BZOJ4340][BJOI2015]隐身术(后缀数组)

    考虑到K很小,于是可以暴搜每次用的是哪种操作,跳过AB相等的字符可以用SA求LCP加速. 主要流程就是,枚举B的每个后缀,对每个后缀统计合法前缀个数.DFS搜索每次决策,用SA跳过相同字符,当A或B匹 ...

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

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

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

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

  4. BJOI2015 隐身术

    落谷. Description 给你两个串 \(A.B\).询问 \(B\) 中有多少个非空子串和 \(A\) 的编辑距离不超过 \(K\). Solution 发现 \(K \le 5\),考虑可以 ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. BZOJ 4337: BJOI2015 树的同构 树hash

    4337: BJOI2015 树的同构 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4337 Description 树是一种很常见的数 ...

  7. bzoj4337: BJOI2015 树的同构 树哈希判同构

    题目链接 bzoj4337: BJOI2015 树的同构 题解 树哈希的一种方法 对于每各节点的哈希值为hash[x] = hash[sonk[x]] * p[k]; p为素数表 代码 #includ ...

  8. 【BZOJ4337】BJOI2015 树的同构 括号序列

    [BZOJ4337]BJOI2015 树的同构 Description 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱 ...

  9. [BZOJ4337][BJOI2015]树的同构(树的最小表示法)

    4337: BJOI2015 树的同构 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1023  Solved: 436[Submit][Status ...

随机推荐

  1. Linux中常用的查看系统信息的命令

    导读 Linux是一个神奇而又高效的操作系统,学完Linux对Linux系统有一个熟悉的了解后,你需要了解下这些实用的查看系统信息的命令. 查看系统版本命令 uname 谈到系统版本就一定会想到una ...

  2. [BZOJ1101][POI2007]Zap

    [BZOJ1101][POI2007]Zap 试题描述 FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd ...

  3. DCMTK354之VC++ 2008 MFC应用程序配置完整过程

    花了一个礼拜,终于在VC++2008 MFC 应用程序中完成了首个基于DCMTK354的首个程序ECHOSCUWIN32,现将过程记录下来,便于日后查阅,同时也提供给那些有幸看到此博文而对他们又有帮助 ...

  4. Python os.system 和 os.popen的区别

    (1) os.system # 仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 system(command) -> exit_statusExecute the command ...

  5. 【GoLang】GoLang GOPATH 工程管理 最佳实践

    参考资料: MAC下 Intellij IDEA GO语言插件安装及简单案例:http://blog.csdn.net/fenglailea/article/details/53054502 关于wi ...

  6. 4.在二元树中找出和为某一值的所有路径[FindPathsInBinaryTree]

    [题目]: 输入一个整数和一棵二元树.从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径.打印出和与输入整数相等的所有路径. 例如输入整数22和如下二元树 10              ...

  7. 利用VMware虚拟机(Android-x86 2.2)和eclipse,调试安卓代码

    下载 android-x86-2.2-generic.iso (这里包含eth0)  http://www.android-x86.org/download XP32位 只能使用 VMware Wor ...

  8. DP:Dollar Dayz(POJ 3181)

    一道高精度DP 题目大意,换工具,有m块钱,有k种价值的物品,(1...k),求一共有多少种换法 这一题就是完全背包,现在这种完全背包对我来说就是水题了, 状态转移方程闭着眼睛写dp[j]+=dp[j ...

  9. mybatisforeach循环,传入多个参数

    上代码: controller: @RequestMapping(value = "/findPage", method = RequestMethod.POST) @Respon ...

  10. javascript 中string 型数据转换成int类型

    var str1 = "1234";var str2 = "1234";number = parseInt(str1); number就是int型 str1+s ...