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的差距是多少,两个串的差距就是每次把一个字符变成另一个字 ...
随机推荐
- java基础知识查漏 三
一.Servlet 和Jsp的生命周期 1.Servlet生命周期 Servlet是运行在Servlet容器(有时候也叫Servlet引擎,是web服务器和应用程序服务器的一部分,用于在发 ...
- python数据分析之ipython
在用python进行数据分析的时候,需要提前安装如下几个库: Numpy:是python进行科学计算的科学包 pandas:提供了能够快速便捷地处理结构化数据的大量数据结构和函数 matplotlib ...
- 【Effective C++】资源管理
资源:动态分配的内存.文件描述器.互斥锁.图形界面中的字型与笔刷.数据库连接以及网络sockets等,无论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统. 条款13:以对象管理资源 当我们向 ...
- Machine Learning in Action(2) 决策树算法
决策树也是有监督机器学习方法. 电影<无耻混蛋>里有一幕游戏,在德军小酒馆里有几个人在玩20问题游戏,游戏规则是一个设迷者在纸牌中抽出一个目标(可以是人,也可以是物),而猜谜者可以提问题, ...
- animation steps属性实现帧动画
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta na ...
- Codeforces Round #138 (Div. 2) A. Parallelepiped
A. Parallelepiped time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- 花了5天时间,终于解决了一个bug,心情非常愉快,憋了这么久,不吐不快
http://www.cnweblog.com/fly2700/archive/2011/12/06/318916.html (转载) 花了5天时间,终于解决了一个bug,心情非常愉快,憋了这么久,不 ...
- linux应用之用户管理相关命令
1. useradd useradd 命令可以创建一个新的用户帐号,其最基本用法为: useradd 用户名 如输入以下命令: useradd newuser 系统将创建一个新用户 newuser,该 ...
- 安装asterisk以及asterisk-gui
asterisk的安装在ubuntu上自我感觉还是很方便的,虽然也会遇到一些小的问题.下面是本人遇到的 一些问题和解决方法. 1>在ubuntu10.04上安装aste ...
- Java应用架构设计模块化模式与OSGI摘录
在Java中,最适合模块化的单元就是Jar文件. 代码层面我们关注的太多了,熟练的开发人员现在很少争论使用模式的好处,也不再识别哪个模式适合当前需要,因为都能够本能地使用各种设计原则和模式,从GoF的 ...