UVALive4671   K-neighbor substrings   给定一个两个字符串A和B B为模式串。问A中有多少不同子串与B的距离小于k 所谓距离就是不同位的个数。

由于字符串只包含a和b 我们可以换做0和1 将B反转 进行大整数乘法(卷积) 就可以轻松得出不同的位数。只有FFT能在nlogn时间内完成大整数乘法。

要求不同的子串,再进行一次字符串散列即可。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<stack>
#include<complex>
//使用FFT时注意精度问题和数组大小
using namespace std;
typedef long long int LL;
const double pi=acos(-1.0);
struct Complex {
double r, i;
Complex(double _r, double _i) {
r = _r;
i = _i;
}
double real()
{
return r;
}
double ii()
{
return i;
}
Complex operator + (const Complex &c) {
return Complex(c.r + r, c.i + i);
}
Complex operator - (const Complex &c) {
return Complex(r - c.r, i - c.i);
}
Complex operator * (const Complex &c) {
return Complex(c.r * r - c.i * i, c.r * i + c.i * r);
}
Complex operator / (const int &c) {
return Complex(r / c, i / c);
}
Complex(){}
};
void build(Complex _P[],Complex P[],LL n,LL m,LL curr,LL &cnt)
{
if(n==m){_P[curr]=P[cnt++];}
else {build(_P,P,n,m*2,curr,cnt);build(_P,P,n,m*2,curr+m,cnt);} }
const LL maxn=300000;
void FFT(Complex P[],LL n,LL oper)//返回结果向左靠齐 最后结果除n
{
static Complex _P[maxn];
LL cnt=0;
build(_P,P,n,1,0,cnt);copy(_P,_P+n,P);
for(LL d=0;(1<<d)<n;d++)
{
LL m=1<<d;
LL m2=m*2;
double p0=pi/m*oper;
Complex unit_p0=Complex(cos(p0),sin(p0));
for(LL i=0;i<n;i+=m2)
{
Complex unit=Complex(1,0);
for(LL j=0;j<m;j++)
{
Complex &P1=P[i+j+m],&P2=P[i+j];
Complex t=unit*P1;
P1=P2-t;
P2=P2+t;
unit=unit*unit_p0;
}
}
}
}
void himult(Complex p1[],Complex p2[],LL n,Complex ans[])
{ FFT(p1,n,1);FFT(p2,n,1);
for(LL i=0;i<=n;i++)
ans[i]=p1[i]*p2[i];
FFT(ans,n,-1);
}
char a[131072*2],b[131072*2];
Complex av[131072*4],bv[131072*2+1],ans1[131072*2+1];
unsigned long long int ha[200000],xp[200000];
const int seed=3;
set<unsigned long long int >vise;
bool hash(int l,int r)
{
unsigned long long int nowv= ha[r+1]-ha[l]*xp[r-l+1];
if(vise.count(nowv)==0){vise.insert(nowv);return false;}
else return true;
}
int main()
{
freopen("t.txt","r",stdin);
xp[0]=1;
for(int i=1;i<=100000;i++)
xp[i]=xp[i-1]*seed;
int ii=0;
while(1)
{ ii++;
vise.clear();
int k;
scanf("%d",&k);
if(k==-1)break;
memset(a,0,sizeof(a));memset(b,0,sizeof(b));
scanf("%s%s",&a,&b);
int la=strlen(a),lb=strlen(b);
int len=1;
while(len<=la+lb)len<<=1;
for(int i=0;i<la;i++)
av[i]=Complex(a[i]=='a'?1:-1,0);
for(int i=la;i<=len;i++)av[i]=Complex(0,0);
for(int i=0;i<lb;i++)
bv[lb-i-1]=Complex(b[i]=='a'?1:-1,0);
for(int i=lb;i<=len;i++)
bv[i]=Complex(0,0);
memset(ans1,0,sizeof(ans1));
himult(av,bv,len,ans1);
int anss=0;
ha[0]=0;
for(int i=0;i<la;i++)
ha[i+1]=ha[i]*seed+a[i];
for(int i=0;i+lb<=la;i++)
{
if(hash(i,i+lb-1))continue;
int nue=(int)(ans1[i+lb-1].r/len+0.5);
if(lb-nue<=k*2)anss++;
}
printf("Case %d: %d\n",ii,anss);
}
return 0;
}

  

UVALive 4671 K-neighbor substrings 巧用FFT的更多相关文章

  1. UVALive 7721 K - 2-ME Set 集合dp,所有数的位或来表示状态。

    /** 题目:UVALive 7721 K - 2-ME Set 链接:https://vjudge.net/problem/UVALive-7721 题意:给定n个数,从中取出一个集合,至少包含两个 ...

  2. UVALive - 4671 K-neighbor substrings (FFT+哈希)

    题意:海明距离的定义:两个相同长度的字符串中不同的字符数.现给出母串A和模式串B,求A中有多少与B海明距离<=k的不同子串 分析:将字符a视作1,b视作0.则A与B中都是a的位置乘积是1.现将B ...

  3. UVALive - 6886 Golf Bot 多项式乘法(FFT)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/129724 Golf Bot Time Limit: 15000MS 题意 给你n个数,m个查询,对于每个查询 ...

  4. loj #6247. 九个太阳 k次单位根 神仙构造 FFT求和原理

    LINK:九个太阳 不可做系列. 构造比较神仙. 考虑FFT的求和原理有 \(\frac{1}{k}\sum_{j=0}^{k-1}(w_k^j)^n=[k|n]\) 带入这道题的式子. 有\(\su ...

  5. UVALive - 6257 K - Chemist's vows 【DFS】【BFS】【DP】

    题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  6. CodeForces - 528D Fuzzy Search (FFT求子串匹配)

    题意:求母串中可以匹配模式串的子串的个数,但是每一位i的字符可以左右偏移k个位置. 分析:类似于 UVALive -4671. 用FFT求出每个字符成功匹配的个数.因为字符可以偏移k个单位,先用尺取法 ...

  7. 快速傅里叶变换FFT

    多项式乘法 #include <cstdio> #include <cmath> #include <algorithm> #include <cstdlib ...

  8. 用于ARM上的FFT与IFFT源代码(C语言,不依赖特定平台)(转)

    源:用于ARM上的FFT与IFFT源代码(C语言,不依赖特定平台) 代码在2011年全国电子大赛结束后(2011年9月3日)发布,多个版本,注释详细. /*********************** ...

  9. FFT\NTT总结

    学了好久,终于基本弄明白了 推荐两个博客: 戳我 戳我 再推荐几本书: <ACM/ICPC算法基础训练教程> <组合数学>(清华大学出版社) <高中数学选修> 预备 ...

随机推荐

  1. Java变量及数据类型

    变量及数据类型 变量 变量定义格式:数据类型 变量名 = 初始化值; 基本数据类型 整形数据 package com.ahabest.demo; //输出整形数据的最小值,默认值,最大值,二进制位数 ...

  2. 08Oracle Database 完整性约束

    Oracle Database 完整性约束 非空约束 创建表时 Create table table_name( Column_name datatype NOT NULL,… ); 修改表时 Alt ...

  3. 小程序button默认样式透彻理解

    微信小程序有一个默认样式,特别是有一个外边框,虽然看起来不别扭,但是自己每次设置border:0:都不生效,写成内联的样式也不生效,后来才知道里面的边框是伪元素的边框,这里的伪元素可以理解为用css动 ...

  4. Socket中BufferedReader.readLine()的阻塞特性导致的数据无法多次发送的问题

    https://blog.csdn.net/shenpibaipao/article/details/70236657

  5. TestNG忽略测试

    用@Test(enabled = false) 声明需要被忽略执行的测试方法 package com.janson; import org.testng.annotations.Test; publi ...

  6. Django基础——ORM字段和字段参数

    ORM概念: 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象( 1. 不同的程序员写的SQL水平参差不齐 2. ...

  7. QQ帐户的申请与登陆

    QQ帐户的申请与登陆 实现QQ新帐户申请和老帐户登陆的简化版功能.最大挑战是:据说现在的QQ号码已经有10位数了. 输入格式: 输入首先给出一个正整数N(≤10^5,随后给出N行指令.每行指令的格式为 ...

  8. TensorFlow Ops

    TensorFlow Ops 1. Fun with TensorBoard In TensorFlow, you collectively call constants, variables, op ...

  9. [luoguP1586] 四方定理(DP 背包)

    传送门 相当于背包, f[i][j] 表示当前数为 i,能分解成 j 个数的平方的和的数量 那么就是统计背包装物品的数量 ——代码 #include <cmath> #include &l ...

  10. 临时起异,要进入C++领域耍一个程序

    没办法.两周之内可以搞定吧. 就一个SESSION 0的问题. 网上有类似源码,调一下应该就可以吧..保佑顺利. 基本语法都还记得,快N年啦... #include <iostream> ...