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的差距是多少,两个串的差距就是每次把一个字符变成另一个字 ...
随机推荐
- iframe调用父页面js函数 方法 元素
在一个页面中添加iframe,但是有时需要与父页面进行通信,传递参数. 网上总结有以下方法: 一.iframe标签中 src属性传参 <iframe src="test.jsp?i ...
- Building REST services with Spring
https://spring.io/guides/tutorials/bookmarks/
- Find out when memory leaks are a concern and how to prevent them
Handling memory leaks in Java programs Find out when memory leaks are a concern and how to prevent t ...
- Javascript的参数详解
函数可以有参数也可以没有参数,如果定义了参数,在调用函数的时候没有传值,默认设置为undefined 在调用函数时如果传递参数超过了定义时参数,jS会忽略掉多余参数 jS中不能直接写默认值,可以通过a ...
- 把tomcat写到Windows系统服务器的服务中
首先准备一个免安装的tomcat服务器,和一个Windows系统. 在“C:\Windows\SysWOW64”中找到cmd.exe的执行文件,以管理员身份启动: 进入到tomcat的bin文件夹, ...
- Machine Learning in Action(5) SVM算法
做机器学习的一定对支持向量机(support vector machine-SVM)颇为熟悉,因为在深度学习出现之前,SVM一直霸占着机器学习老大哥的位子.他的理论很优美,各种变种改进版本也很多,比如 ...
- unity导出android项目
1. 2 . 3 选择Google Android Project(若不选则直接导出Apk) Export,Android项目即可导出成功.
- HDU3480 Division —— 斜率优化DP
题目链接:https://vjudge.net/problem/HDU-3480 Division Time Limit: 10000/5000 MS (Java/Others) Memory ...
- 确定mapkeeper使用的leverdb库路径
目前libleveldb的a或so库有三个路径,/usr/lib, /usr/lib/x86_64-linux-gnu , /usr/local/lib 使用 ls -d -1 /usr/lib/* ...
- Python: PS 图像调整--饱和度调整
本文用 Python 实现 PS 图像调整中的饱和度调整算法,具体的算法原理和效果可以参考之前的博客: http://blog.csdn.net/matrix_space/article/detail ...