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. C的指针疑惑:C和指针13(高级指针话题)

    传递命令行参数 C程序的main函数具有两个形参.第一个通常称为argc,代表命令行参数的数目. 第二个通常称为argv,它指向一组参数值.由于参数的数目并没有内在的限制,所以argv指向这组参数值( ...

  2. hash 冲突及解决办法。

    hash 冲突及解决办法. 关键字值不同的元素可能会映象到哈希表的同一地址上就会发生哈希冲突.解决办法: 1)开放定址法:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列.沿 ...

  3. 转:WebClient类(温习一下)

    WebClient类提供向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法. 其实就相当于创建一个请求客户端.可以获取网页和各种各样的信息,包括交互. 通过MSDN来看看WebC ...

  4. XDU 1109

    #include<stdio.h> #define N 10007 #define maxn 1000005 int dp[maxn]; int main() { dp[]=,dp[]=, ...

  5. Oracle 分组函数

    分组函数的介绍 分组函数作用于一组数据,并对一组数据返回一个值. (引用网上的一张图) 分组函数的使用规则 SELECT [column,] group_function(column) FROM t ...

  6. 150. Evaluate Reverse Polish Notation(逆波兰表达式)

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

  7. mongodb中的_id的ObjectId的生成规则

    MongoDB中存储的文档必须有一个"_id" .这个键值可以是任何类型,默认是ObjectID对象.在一个集合里,每个文档都有一个唯一的“_id”,确保集合里的每个文档都能被唯一 ...

  8. python将一些朋友的姓名存储在一个列表中,访问该列表中的每个元素,从而将每个朋友的姓名都打印出来

    """ 3-1 姓名: 将一些朋友的姓名存储在一个列表中,并将其命名为 names . 依次访问该列表中的每个元素,从而将每个朋友的姓名都打印出来. "&quo ...

  9. 【Error】安装程序无法打开注册表项 UNKNOWN\Components\...

    在安装程序的时候出现错误信息: 解决方法: 依次点击开始,所有程序,附件,右键单击命令提示符,选择以管理员身份运行.运行secedit /configure /cfg %windir%\inf\def ...

  10. 20145314郑凯杰 《Java程序设计》实验五 实验报告

    20145314郑凯杰 <Java程序设计>实验五 实验报告 实验搭档王亦徐:http://www.cnblogs.com/1152wyx/p/5471524.html 实验要求 完成实验 ...