【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. 在BAE上部署Pomelo

    BAE升级到3.0后顿时感觉好用了很多,俨然云主机的感觉. 底下我将分享我在BAE上部署Pomelo的过程. 首先需要拥有一个BAE的执行单元.没有的可以自行百度并部署. 接着svn得出代码到本地.此 ...

  2. javaweb(十一)——使用Cookie进行会话管理

    一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾 ...

  3. 九、EnterpriseFrameWork框架基础功能之消息管理

    记得阿朱在<走出软件作坊>一书中有一章讲客户提的需求太邪门了,鼠标键盘不太会用要程序员开发一个语音输入功能,还要系统中带类似QQ的功能:确实刚开始的客户的想法有点天真,但是随着信息化的越来 ...

  4. python基础数据类型3

    python_day_5 今日大纲: 1. dict 用大括号{} 括起来. 内部使用key:value的形式来保存数据 {'jay':'周杰伦', "jj":'林俊杰'} 注意: ...

  5. Docker虚拟机172.17网段冲突,导致网络访问问题

    在虚拟机中安装docker,linux ubuntu16 ,安装完公司172.17网段被docker0覆盖,导致ssh无法连接到ubuntu. 经过官网的这篇build your own bridge ...

  6. 使用HackRF和外部时钟实现GPS欺骗实验

    本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 HackRF链接:https://item.taobao.com/item.htm?spm=a1z10.1- ...

  7. Linux内核学习笔记(7)--完全公平调度(CFS)

    一.完全公平调度算法 完全公平调度 CFS 的出发点基于一个简单的理念:进程调度的效果应该如同系统具备一个理想中的完美多任务处理器.在这种系统中,每个进程能够获得 1/n 的处理器时间(n 为可运行进 ...

  8. 获取秒级时间戳和毫秒级时间戳---基于python

    获取秒级时间戳和毫秒级时间戳 import timeimport datetime t = time.time() print (t) #原始时间数据print (int(t)) #秒级时间戳prin ...

  9. 汉诺塔python实现

    下载汉诺塔ppt def move(n,A,B,C): if n == 1: print(A,'->',C) else: move(n-1,A,C,B) print(A,'->',C) m ...

  10. P4tutorial实战

    Tutorial样例实战 GitHub仓库地址 参考博客 实验一:SIGCOMM_2015/Sourse_Routing 实验环境: OS:Ubuntu16.04 bmv2:behavioral-mo ...