CF954I Yet Another String Matching Problem(FFT+并查集)
给定两个字符串\(S,T\)
求\(S\)所有长度为\(|T|\)子串与\(T\)的距离
两个等长的串的距离定义为最少的,将某一个字符全部视作另外一个字符的次数。
\(|T|<=|S|<=10^6\),字符集大小为\(6\)
题解
首先考虑对于两个长度相等的子串怎么比较他们的距离,那么就是一个CF939D Love Rescue,一遍扫过去,如果对应位置的字符不相等且不在同一个并查集内那么连边并\(++ans\)
因为字符集大小只有\(6\),边的种类只有\(30\)种,所以我们可以考虑对于每一个子串,每一条边是否要连。把\(T\)翻转,考虑枚举字符\(i,j\),把\(S\)串\(i\)出现的位置对应为\(1\),\(T\)串\(j\)出现的位置对应为\(1\),画个图理解一下,如果以\(S\)中以\(x\)结尾的长度为\(|T|\)的子串中有\(i,j\)这一条边,那么在把上式卷积之后,\(x\)位置肯定为不为\(0\)
于是暴力枚举字符集,对于每一个结尾位置维护一下边的情况,然后跑并查集就是了
//minamoto
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=5e5+5;const double Pi=acos(-1.0);
struct complex{
double x,y;
complex(double xx=0,double yy=0){x=xx,y=yy;}
inline complex operator +(const complex &b){return complex(x+b.x,y+b.y);}
inline complex operator -(const complex &b){return complex(x-b.x,y-b.y);}
inline complex operator *(const complex &b){return complex(x*b.x-y*b.y,x*b.y+y*b.x);}
}A[N],B[N],O[N];
int r[N],eq[N][6][6],fa[6],n,m,lim,l,res;
char a[N],b[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void FFT(complex *A,int ty){
fp(i,0,lim-1)if(i<r[i])std::swap(A[i],A[r[i]]);
for(R int mid=1;mid<lim;mid<<=1){
int I=(mid<<1);complex Wn(cos(Pi/mid),ty*sin(Pi/mid));
fp(i,1,mid-1)O[i]=O[i-1]*Wn;
for(R int j=0;j<lim;j+=I)fp(k,0,mid-1){
complex x=A[j+k],y=O[k]*A[j+k+mid];
A[j+k]=x+y,A[j+k+mid]=x-y;
}
}
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%s%s",a,b);
n=strlen(a),m=strlen(b);
lim=1;while(lim<=n+m)lim<<=1,++l;O[0]=complex(1,0);
fp(i,0,lim-1)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
fp(i,0,5)fp(j,0,5){
fp(k,0,lim-1)A[k].x=B[k].x=A[k].y=B[k].y=0;
fp(k,0,n-1)A[k].x=(a[k]==i+'a');
fp(k,0,m-1)B[k].x=(b[m-k-1]==j+'a');
FFT(A,1),FFT(B,1);
fp(k,0,lim-1)A[k]=A[k]*B[k];
FFT(A,-1);
fp(k,0,lim-1)eq[k][i][j]=(int)(A[k].x/lim+0.5);
}fp(i,m-1,n-1){
fp(j,0,5)fa[j]=j;
fp(j,0,5)fp(k,0,5)
if(eq[i][j][k])fa[find(j)]=find(k);
res=0;
fp(j,0,5)if(find(j)!=j)++res;
printf("%d ",res);
}return 0;
}
CF954I Yet Another String Matching Problem(FFT+并查集)的更多相关文章
- Codeforces 954I Yet Another String Matching Problem(并查集 + FFT)
题目链接 Educational Codeforces Round 40 Problem I 题意 定义两个长度相等的字符串之间的距离为: 把两个字符串中所有同一种字符变成另外一种,使得两个 ...
- CF954I Yet Another String Matching Problem 并查集、FFT
传送门 题意:给出两个由小写$a$到$f$组成的字符串$S$和$T$($|S| \geq |T|$),给出变换$c1\,c2$表示将两个字符串中所有$c1$字符变为$c2$,求$S$的每一个长度为$T ...
- Codeforces.954I.Yet Another String Matching Problem(FFT)
题目链接 \(Description\) 对于两个串\(a,b\),每次你可以选择一种字符,将它在两个串中全部变为另一种字符. 定义\(dis(a,b)\)为使得\(a,b\)相等所需的最小修改次数. ...
- CF954I Yet Another String Matching Problem
传送门 每次操作可以把两个字符串中所有同一种字符变成另外一种 定义两个长度相等的字符串之间的距离为:使两个字符串相等所需要操作的次数的最小值 求 \(s\) 中每一个长度为 \(|t|\) 的连续子串 ...
- 【CF954I】Yet Another String Matching Problem(FFT)
[CF954I]Yet Another String Matching Problem(FFT) 题面 给定两个字符串\(S,T\) 求\(S\)所有长度为\(|T|\)的子串与\(T\)的距离 两个 ...
- 954I Yet Another String Matching Problem
传送门 分析 我们先考虑暴力如何计算 对于S的子串SS,如果它有位置i使得SS[i] != T[i]那么我们就将两个字符之间用并查集连边 最后答案很明显就是并查集中所有边的个数 于是我们可以发现对于S ...
- 1034. Head of a Gang (30) -string离散化 -map应用 -并查集
题目如下: One way that the police finds the head of a gang is to check people's phone calls. If there is ...
- CodeForces - 827A:String Reconstruction (基础并查集)
Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun ...
- Educational Codeforces Round 40 I. Yet Another String Matching Problem
http://codeforces.com/contest/954/problem/I 给你两个串s,p,求上一个串的长度为|p|的所有子串和p的差距是多少,两个串的差距就是每次把一个字符变成另一个字 ...
随机推荐
- EasyRTSPClient:基于live555封装的支持重连的RTSP客户端RTSPClient
今天先简单介绍一下EasyRTSPClient,后面的文章我们再仔细介绍EasyRTSPClient内部的设计过程: EasyRTSPClient:https://github.com/EasyDar ...
- JavaScript精粹
序:好书是需要不断品读的!再读语言精粹,顺便做点笔记. 1.NaN是一个数值,它表示一个不能产生正常结果的运算结果.NaN不等于任何值,包括它自己.检测是否为NaN: isNaN(number). ...
- 如何解决Apache无法启动的问题
今天重装xampp后,一直无法启动Apache,提示以下错误: 22:36:54 [Apache] Attempting to start Apache app...22:36:54 [Apache] ...
- Linux就该这么学--命令集合2(系统状态检测命令)
1.查看本机当前的网卡配置与网络状态等信息:(ifconfig [网络设备] [参数]) ifconfig 2.查看系统的内核名称.内核发行版.内核版本.节点名.硬件名称.硬件平台.处理器类型.操作系 ...
- Debug 和 Release 的区别
Debug 和 Release 的区别 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程 ...
- 20170313 ABAP以jason 格式返回值到http(接口内容返回)
问题1: 返回jason 格式信息给你们这步不通, 这个可以怎么处理, ***得到SCP 系统开发回复,他们需要调整方法: (1)调用函数做RETURN, IT_ZSMLSCPNOTICE-FUNC ...
- chrome最小字体12px
http://www.mamicode.com/info-detail-512021.html http://www.divcss5.com/wenji/w738.shtml
- UVA10518 How Many Calls? —— 矩阵快速幂
题目链接:https://vjudge.net/problem/UVA-10518 题解: 问:求斐波那契数f[n]的时候调用了多少次f[n] = f[n-1] + f[n-2],没有记忆化,一直递归 ...
- Win8风格的WPF按钮
Win8将Windows的风格又进行了一次变革,我还挺喜欢的,有简洁大气的感觉,华丽绚丽的东西看多了之后总会返璞归真寻找简洁大气的感觉才能心情舒畅. 下面就给个WPF下Button的自定义写法. ...
- jmeter解压后启动jmeter.bat报错:Not able to find java executable or version
错误详情: 错误解决方法: 修改环境变量配置将%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;移动到%SystemRoot%\system32;%SystemRoot%;%Sy ...