http://codeforces.com/contest/954/problem/I

给你两个串s,p,求上一个串的长度为|p|的所有子串和p的差距是多少,两个串的差距就是每次把一个字符变成另一个字符的最小次数,字符最大到f

很明显,如果知道每两个串对应地方不相同的字符就能通过dfs/dsu解出来,那么如何快速的找到所有对应的不匹配的地方呢,

我们先单独考虑两个不同的字符,比如abada中取a,cba中取c,用二进制1代表选取的字符表示就是10101,100,我们用fft来加速这一过程

1  2  3  4  5    1  2  3     ------->     n-1 n-2 n-3

1  0  1  0  1    1  0  0       1  0   0

4  3  1

0  0  1

直接乘的话复杂度还是很高,我们把后一个串转一下变成001,这样如果要找最开始的串和p匹配是不是就系数是5看fft之后的系数是不是1,然后以此类推第二个是6,这样一遍fft就能求出所有情况,然后一共需要fft6*6次,复杂度(O(36*nlogn))

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod (1000000007)
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
//#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; struct cd
{
double x,y;
cd(double _x=0.0,double _y=0.0):x(_x),y(_y){}
cd operator + (const cd &b)const
{
return cd(x+b.x,y+b.y);
}
cd operator - (const cd &b)const
{
return cd(x-b.x,y-b.y);
}
cd operator * (const cd &b)const
{
return cd(x*b.x-y*b.y,x*b.y+y*b.x);
}
cd operator / (const double &b)const
{
return cd(x/b,y/b);
}
}a[N<<],b[N<<];
int rev[N<<];
void getrev(int bit)
{
for(int i=; i<(<<bit); i++)
rev[i]=(rev[i>>]>>)|((i&)<<(bit-));
}
void fft(cd* a,int n,int dft)
{
for(int i=; i<n; i++)
if(i<rev[i])
swap(a[i],a[rev[i]]);
for(int step=; step<n; step<<=)
{
cd wn(cos(dft*pi/step),sin(dft*pi/step));
for(int j=; j<n; j+=step<<)
{
cd wnk(,);
for(int k=j; k<j+step; k++)
{
cd x=a[k];
cd y=wnk*a[k+step];
a[k]=x+y;
a[k+step]=x-y;
wnk=wnk*wn;
}
}
}
if(dft==-)for(int i=; i<n; i++)a[i]=a[i]/n;
}
char s[N],p[N];
bool ok[N][][];
int fa[];
int Find(int x)
{
return fa[x]==x?x:fa[x]=Find(fa[x]);
}
int main()
{
scanf("%s%s",s+,p+);
int n=strlen(s+),m=strlen(p+);
int sz=;
while((<<sz)<n)sz++;
sz++;getrev(sz);
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
if(i==j)continue;
for(int k=;k<=(<<sz);k++)a[k]=b[k]=;
for(int k=;k<=n;k++)a[k]=(s[k]==i+'a');
for(int k=;k<=m;k++)b[n-k]=(p[k]==j+'a');
fft(a,(<<sz),);fft(b,(<<sz),);
for(int k=;k<=(<<sz);k++)a[k]=a[k]*b[k];
fft(a,(<<sz),-);
for(int k=;k<=n-m;k++)ok[k][i][j]=(a[n+k].x>=0.5);
}
}
for(int i=;i<=n-m;i++)
{
for(int j=;j<;j++)fa[j]=j;
int ans=;
for(int j=;j<;j++)
{
for(int k=;k<;k++)
{
if(j==k)continue;
int fj=Find(j),fk=Find(k);
if(ok[i][j][k]&&fj!=fk)fa[fj]=fk,ans++;
}
}
printf("%d ",ans);
}
puts("");
return ;
}
/********** **********/

Educational Codeforces Round 40 I. Yet Another String Matching Problem的更多相关文章

  1. Educational Codeforces Round 40千名记

    人生第二场codeforces.然而遇上了Education场这种东西 Educational Codeforces Round 40 下午先在家里睡了波觉,起来离开场还有10分钟. 但是突然想起来还 ...

  2. [Educational Codeforces Round 16]E. Generate a String

    [Educational Codeforces Round 16]E. Generate a String 试题描述 zscoder wants to generate an input file f ...

  3. Educational Codeforces Round 40 F. Runner's Problem

    Educational Codeforces Round 40 F. Runner's Problem 题意: 给一个$ 3 * m \(的矩阵,问从\)(2,1)$ 出发 走到 \((2,m)\) ...

  4. Educational Codeforces Round 40 C. Matrix Walk( 思维)

    Educational Codeforces Round 40 (Rated for Div. 2) C. Matrix Walk time limit per test 1 second memor ...

  5. Educational Codeforces Round 40 (Rated for Div. 2) Solution

    从这里开始 小结 题目列表 Problem A Diagonal Walking Problem B String Typing Problem C Matrix Walk Problem D Fig ...

  6. Educational Codeforces Round 16 E. Generate a String dp

    题目链接: http://codeforces.com/problemset/problem/710/E E. Generate a String time limit per test 2 seco ...

  7. Educational Codeforces Round 9 C. The Smallest String Concatenation 排序

    C. The Smallest String Concatenation 题目连接: http://www.codeforces.com/contest/632/problem/C Descripti ...

  8. Educational Codeforces Round 8 C. Bear and String Distance 贪心

    C. Bear and String Distance 题目连接: http://www.codeforces.com/contest/628/problem/C Description Limak ...

  9. Educational Codeforces Round 9 C. The Smallest String Concatenation —— 贪心 + 字符串

    题目链接:http://codeforces.com/problemset/problem/632/C C. The Smallest String Concatenation time limit ...

随机推荐

  1. TensorFlow学习笔记(四)图像识别与卷积神经网络

    一.卷积神经网络简介 卷积神经网络(Convolutional Neural Network,CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现. ...

  2. 编写项目readme文件

    1.使用markdown 编写项目说明,markdown 编辑器推荐使用 小书匠 2.在当前项目根目录下使用cmd中的tree 命令 生成项目结构文件到指定的txt文件中,具体命令为:tree d: ...

  3. 使用Echarts进行可视化的数据线呈现

    由于游戏后台需要统计游戏玩家的支付情况,恰好那天看见同学群里聊天说到了Echarts,于是我就看了眼,一看,哟,还是百度的产品,看了文档,示例,确实很屌的样子啊,于是自己就开始试了,最终效果如下: 个 ...

  4. delphi pchar 指针错误

    2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var P: Pchar; //P 是指针 CSize: Cardinal; ...

  5. npm使用淘宝镜像

    淘宝 npm 地址: http://npm.taobao.org/ 如何使用 有很多方法来配置npm的registry地址,下面根据不同情境列出几种比较常用的方法.以淘宝npm镜像举例: 1.临时使用 ...

  6. 【android】通过leakCanary找出程序内存泄露点

    背景 内存泄露是咱新手比较头痛的问题,因为它不像崩溃,在开发环境可以根据提示的错误信息排查问题. 你都不知道咱的app是否哪个犄角旮旯藏着一个吞噬内存的黑洞. 排查android 内存泄露比较底层高端 ...

  7. Java堆内存设置

    转自:https://blog.csdn.net/Qiuzhongweiwei/article/details/81023645 堆内存设置 原理 JVM堆内存分为2块:永久空间和堆空间. 永久即持久 ...

  8. 20145316《Java程序设计》第二周学习总结

    20145316<Java程序设计>第2周学习总结 教材学习内容总结 3.1.1 Java的类型 分为基本类型(Primitive type)和类类型(Class type) 基本类型: ...

  9. JavaScript 事件处理详解

    事件绑定与解绑: el.onEventName = function (){} document.getElementById("dom").onclick = function( ...

  10. Windows Update error 80070003

    上次更新完成一半,这次更新便会出错.办法:删除上次更新残余文件. 删除Windows 用于标识计算机更新的临时文件.需要先停止Windows Update 服务: 在开始菜单的“搜索程序和文件”框输入 ...