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的差距是多少,两个串的差距就是每次把一个字符变成另一个字 ...
随机推荐
- 开源G711A/PCMA、G711U/PCMU、G726、PCM转码AAC项目EasyAACEncoder
项目及源码地址:https://github.com/EasyDarwin/EasyAACEncoder EasyAACEncoder 是EasyDarwin开源流媒体服务团队整理.开发的一款音频转码 ...
- 哈希表的java实现
一.为什么要用哈希表 树的操作通常需要O(N)的时间级,而哈希表中无论存有多少数据,它的插入和查找(有时包括删除)只需要接近常量级的时间,即O(1)的时间级. 但是哈希表也有一定的缺点:它是基于数组的 ...
- openjdk源码目录结构
1 openjdk源码 http://hg.openjdk.java.net 选择jdk8u这个project, 然后选择jdk8u20这个repository. 2 目录结构 corba: comm ...
- Write Custom Java to Create LZO Files
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+LZO LanguageManual LZO Skip to e ...
- DuiLib笔记之Control常用属性
name 指定控件名称,同一窗口内必须唯一,类型:STRING float 用于指定控件是否使用绝对定位,或设置FloatPercent,类型:BOOL,默认值为false,格式:float=&quo ...
- 基于springboot的Dubbo的常规总结
1.引入jar包: <!-- Spring Boot Dubbo 依赖 --> <dependency> <groupId>com.alibaba.spring.b ...
- Chrome 插件 Vimium——让你脱离鼠标
下面是帮助,按?就能出现.什么时候忘了可以随时查看.^_^
- html5--4-5 embed元素及其他
html5--4-5 embed元素及其他 学习要点 掌握embed元素的使用 了解object元素的使用 温馨提示:关于video和audio的事件方法等涉及都JavaScript知识的内容,暂时不 ...
- 【Selenium】IE浏览器启动问题
DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();ieCapabilities.setCapabi ...
- ORA-32001:write to SPFILE requested but no SPFILE is in use
oracle报错: ORA-32001:write to SPFILE requested but no SPFILE is in use 解决方法: 1.查看是否有spfile sql> sh ...