【CF954I】Yet Another String Matching Problem(FFT)

题面

给定两个字符串\(S,T\)

求\(S\)所有长度为\(|T|\)的子串与\(T\)的距离

两个等长的串的距离定义为最少的,将某一个字符全部视作另外一个字符的次数。

\(|T|<=|S|<=10^6\),字符集大小为\(6\)

题解

考虑如何快速计算两个串的答案,从左向右扫一遍,如果对应位置上有两个字符不同,检查在并查集中是否属于同一个集合,如果不属于则答案加一,同时合并两个集合。(这个就是CF939D)

如果枚举每一个长度为\(|T|\)的子串,复杂度为\(O(|S||T|)\)。考虑优化。

将\(T\)串反转,枚举两个字符\(x,y\),将\(S\)串的\(x\)字符出现的位置对应为\(1\),\(T\)串的\(y\)字符出现的位置对应为\(1\),其他对应为\(0\),然后求两个生成函数的卷积。

假设在\(T\)的\(a\)位置和\(S\)的\(b\)位置对应有\(1\),那么它们会对\(a+b\)位置对应一个\(1\),也就是\(b+|T|-a\)位置对应一个\(1\),同时意味着在\(S\)的从这个位置开始的长度为\(|T|\)的子串中,这个位置上对应着这两个字符。

于是枚举每个开始的位置,以及任意两个字符,如果在任意位置这两个字符有对应相等的话,并查集合并即可。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 333333
const double Pi=acos(-1);
struct Complex{double a,b;}A[MAX],B[MAX],W[MAX];
Complex operator+(Complex a,Complex b){return (Complex){a.a+b.a,a.b+b.b};}
Complex operator-(Complex a,Complex b){return (Complex){a.a-b.a,a.b-b.b};}
Complex operator*(Complex a,Complex b){return (Complex){a.a*b.a-a.b*b.b,a.a*b.b+a.b*b.a};}
int r[MAX],N,n,m,l,eql[MAX][6][6];
char a[MAX],b[MAX];
void FFT(Complex *P,int opt)
{
for(int i=1;i<N;++i)if(i<r[i])swap(P[i],P[r[i]]);
for(int i=1;i<N;i<<=1)
for(int p=i<<1,j=0;j<N;j+=p)
for(int k=0;k<i;++k)
{
Complex w=(Complex){W[N/i*k].a,W[N/i*k].b*opt};
Complex X=P[j+k],Y=w*P[i+j+k];
P[j+k]=X+Y;P[i+j+k]=X-Y;
}
}
int f[6];
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
int main()
{
scanf("%s",a);scanf("%s",b);
n=strlen(a),m=strlen(b);
for(N=1;N<=(n+m);N<<=1)++l;
for(int i=0;i<N;++i)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
for(int i=1;i<N;i<<=1)
for(int k=0;k<i;++k)W[N/i*k]=(Complex){cos(k*Pi/i),sin(k*Pi/i)};
for(int i=0;i<6;++i)
for(int j=0;j<6;++j)
{
for(int k=0;k<N;++k)A[k].a=A[k].b=B[k].a=B[k].b=0;
for(int k=0;k<n;++k)A[k].a=(a[k]==i+97);
for(int k=0;k<m;++k)B[k].a=(b[m-k-1]==j+97);
FFT(A,1);FFT(B,1);
for(int k=0;k<N;++k)A[k]=A[k]*B[k];
FFT(A,-1);
for(int k=0;k<N;++k)eql[k][i][j]=(int)(A[k].a/N+0.5);
}
for(int i=m-1;i<n;++i)
{
for(int j=0;j<6;++j)f[j]=j;
for(int j=0;j<6;++j)
for(int k=0;k<6;++k)
if(eql[i][j][k])
f[getf(j)]=getf(k);
int ans=0;
for(int j=0;j<6;++j)if(getf(j)!=j)++ans;
printf("%d ",ans);
}
puts("");
return 0;
}

【CF954I】Yet Another String Matching Problem(FFT)的更多相关文章

  1. 【LeetCode】481. Magical String 解题报告(Python)

    [LeetCode]481. Magical String 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http:/ ...

  2. CF954I Yet Another String Matching Problem(FFT+并查集)

    给定两个字符串\(S,T\) 求\(S\)所有长度为\(|T|\)子串与\(T\)的距离 两个等长的串的距离定义为最少的,将某一个字符全部视作另外一个字符的次数. \(|T|<=|S|<= ...

  3. 【LeetCode】394. Decode String 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 栈 日期 题目地址:https://leetcode ...

  4. 【LeetCode】796. Rotate String 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  5. 【LeetCode】767. Reorganize String 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.me/ 题目地址:https://leetcode.com/problems/reorganiz ...

  6. 【Learning】多项式乘法与快速傅里叶变换(FFT)

    简介: FFT主要运用于快速卷积,其中一个例子就是如何将两个多项式相乘,或者高精度乘高精度的操作. 显然暴搞是$O(n^2)$的复杂度,然而FFT可以将其将为$O(n lg n)$. 这看起来十分玄学 ...

  7. 【G】开源的分布式部署解决方案(一) - 开篇

    做这个开源项目的意义是什么?(口水自问自答,不喜可略过) 从功能上来说,请参考 预告篇,因自知当时预告片没有任何含金量,所以并没有主动推送到首页,而是私下的给一些人发的. 从个人角度上来说,我希望.n ...

  8. 【转】python模块分析之typing(三)

    [转]python模块分析之typing(三) 前言:很多人在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数,返回什么类型的结果,就不得不去阅读代码的具体内容,降低了阅读的速度 ...

  9. 【NIFI】 Apache NiFI 之 ExecuteScript处理(二)

    本例介绍NiFI ExecuteScript处理器的使用,使用的脚本引擎ECMScript 接上一篇[NIFI] Apache NiFI 之 ExecuteScript处理(一) ExecuteScr ...

随机推荐

  1. Airflow使用入门指南

    Airflow能做什么 关注公众号, 查看更多 http://mp.weixin.qq.com/s/xPjXMc_6ssHt16J07BC7jA Airflow是一个工作流分配管理系统,通过有向非循环 ...

  2. 查看Linux系统版本的命令

    1.lsb_release -a,即可列出所有版本信息: [root@S-CentOS ~]# lsb_release -a LSB Version: :base-4.0-amd64:base-4.0 ...

  3. Linux 内核3.10.5 专场

    今天本人十分靠谱地下载了linux 内核的3.10.5版本,这个版本是最新的稳定版. 听路飞大虾(哪个路飞?就是那个戴草帽的橡胶小伙,航海很多时候都很空闲的,于是最近他也开始研读linux 内核了.) ...

  4. 高可用Kubernetes集群-3. etcd高可用集群

    五.部署高可用etcd集群 etcd是key-value存储(同zookeeper),在整个kubernetes集群中处于中心数据库地位,以集群的方式部署,可有效避免单点故障. 这里采用静态配置的方式 ...

  5. Centos7下安装Oracle11g r2

    我的centos7是在virtualbox下安装的,安装Oracle安装了好久好久,最开始的时候在网上找的两个文章,按照步骤装,有一篇写着装的时候有灰色的竖线,直接按space键或者鼠标右键close ...

  6. 20172305 2018-2019-1 《Java软件结构与数据结构》第六周学习总结

    20172305 2018-2019-1 <Java软件结构与数据结构>第六周学习总结 教材学习内容总结 本周内容主要为书第十章内容: 树(一种非线性结构,其中的元素被组织成一个层次结构) ...

  7. Python学习笔记(二)--变量和数据类型

    python中的数据类型 python中什么是变量 python中定义字符串 raw字符串与Unicode字符串 python中的整数和浮点数 python中的bool类型 --- python中的数 ...

  8. 七周七语言之用ruby做点什么

    如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/05/25/sevenlang-ruby/. 每学一 ...

  9. 全栈https

    前言:在httpd中使用已经被私有CA签署的证书,对外提供一个https服务 配置httpd服务支持使用https 1:配置httpd支持使用ssl,及使用的证书 yum -y install mod ...

  10. vue-cli脚手架搭建

    我们使用vue-cli来搭建整个项目,vue-cli就是一个脚手架,步骤很简单,输入几个命令之后就会生成整个项目,里面包括了webpack.ESLint.babel很多配置等等,省了很多事 Vue+ ...