4503: 两个串

题意:兔子们在玩两个串的游戏。给定两个只含小写字母的字符串S和T,兔子们想知道T在S中出现了几次,

分别在哪些位置出现。注意T中可能有“?”字符,这个字符可以匹配任何字符。


为什么智障游戏总要让兔子来玩


受到上题影响,直接每个字符算一遍最后加上?的个数,26倍常数完美TLE

上一题是因为母串的每个位置可以匹配几种字符我们才那么做,对于只有相等匹配和万能匹配的问题不用那样做




我们可以直接构造这样一个卷积,

\(a_i=s_i\)

\(b_i=t_i,\ t_i \neq ?\)

\(b_i=0,\ t_i=?\)

\[c_i = \sum_{i=0}^{m-1}(a_{j+i}-b_i)^2b_i=D_{m-1+j}
\]

这样的话能匹配当且仅当相等或者模式串为?

化简后反转模式串就是两个卷积+一个函数卷1加起来的形式

注意:最后一个是\(b_i^3\),如果强行放到fft里计算必须要卷上一个常数函数\(1\)才行,否则直接fft算完后加上他就可以了,他对每一项是相等的




一开始反转模式串的时候直接用t[m-1+i]了wa了好久...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=(1<<18)+5;
const double PI=acos(-1);
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
} struct meow{
double x, y;
meow(double a=0, double b=0):x(a), y(b){}
};
meow operator +(meow a, meow b) {return meow(a.x+b.x, a.y+b.y);}
meow operator -(meow a, meow b) {return meow(a.x-b.x, a.y-b.y);}
meow operator *(meow a, meow b) {return meow(a.x*b.x-a.y*b.y, a.x*b.y+a.y*b.x);}
meow conj(meow a) {return meow(a.x, -a.y);}
typedef meow cd; namespace FFT{
int n, rev[N];
void ini(int lim) {
n=1; int k=0;
while(n<lim) n<<=1, k++;
for(int i=0; i<n; i++) rev[i] = (rev[i>>1]>>1) | ((i&1)<<(k-1));
}
void dft(cd *a, int flag) {
for(int i=0; i<n; i++) if(i<rev[i]) swap(a[i], a[rev[i]]);
for(int l=2; l<=n; l<<=1) {
int m=l>>1;
cd wn = meow(cos(2*PI/l), flag*sin(2*PI/l));
for(cd *p=a; p!=a+n; p+=l) {
cd w(1, 0);
for(int k=0; k<m; k++) {
cd t = w*p[k+m];
p[k+m] = p[k] - t;
p[k] = p[k] + t;
w=w*wn;
}
}
}
if(flag==-1) for(int i=0; i<n; i++) a[i].x/=n;
}
}using FFT::dft; using FFT::ini; int n, m, lim;
cd a[N], b[N], a2[N], b2[N], c[N]; double b3;
char s[N], t[N];
int ans, li[N];
int main() {
freopen("pn","r",stdin);
scanf("%s%s",s,t);
n=strlen(s); m=strlen(t); lim=n+m-1; ini(lim);
for(int i=0; i<n; i++) s[i]=s[i]-'a'+1;
for(int i=0; i<m; i++) t[i]= t[i]=='?' ? 0 : t[i]-'a'+1; for(int i=0; i<n; i++) a[i].x = 2*s[i], a2[i].x = s[i]*s[i];
for(int i=0; i<m; i++) {
int p=m-1-i;
b[p].x = t[i], b2[p].x = t[i]*t[i], b3 += t[i]*t[i]*t[i];
} dft(a, 1); dft(a2, 1); dft(b, 1); dft(b2, 1);
for(int i=0; i<FFT::n; i++) c[i] = a2[i]*b[i] - a[i]*b2[i];
dft(c, -1);
for(int i=0; i<=n-m; i++) if(floor(c[m-1+i].x+b3+0.5)==0) li[++ans]=i;
printf("%d\n",ans);
for(int i=1; i<=ans; i++) printf("%d\n",li[i]);
}

BZOJ 4503: 两个串 [FFT]的更多相关文章

  1. BZOJ.4503.两个串(FFT/bitset)

    题目链接 \(Description\) 给定两个字符串S和T,求T在S中出现了几次,以及分别在哪些位置出现.T中可能有'?'字符,这个字符可以匹配任何字符. \(|S|,|T|\leq 10^5\) ...

  2. bzoj 4503 两个串——FFT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4503 翻转T,就变成卷积.要想想怎么判断. 因为卷积是乘积求和,又想到相等的话相减为0,所以 ...

  3. bzoj 4503 两个串 —— FFT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4503 推式子即可: 不知怎的调了那么久,应该是很清晰的. 代码如下: #include< ...

  4. BZOJ 4503 两个串 ——FFT

    [题目分析] 定义两个字符之间的距离为 (ai-bi)^2*ai*bi 如果能够匹配,从i到i+m的位置的和一定为0 但这和暴力没有什么区别. 发现把b字符串反过来就可以卷积用FFT了. 听说KMP+ ...

  5. bzoj 4503 两个串

    Description 兔子们在玩两个串的游戏.给定两个字符串S和T,兔子们想知道T在S中出现了几次, 分别在哪些位置出现.注意T中可能有“?”字符,这个字符可以匹配任何字符. Input 两行两个字 ...

  6. 【刷题】BZOJ 4503 两个串

    Description 兔子们在玩两个串的游戏.给定两个字符串S和T,兔子们想知道T在S中出现了几次, 分别在哪些位置出现.注意T中可能有"?"字符,这个字符可以匹配任何字符. I ...

  7. BZOJ 4503 两个串(FFT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4503 [题目大意] 给出S串和T串,计算T在S中出现次数,T中有通配符'?'. [题解 ...

  8. bzoj 4503 两个串 快速傅里叶变换FFT

    题目大意: 给定两个\((length \leq 10^5)\)的字符串,问第二个串在第一个串中出现了多少次.并且第二个串中含有单字符通配符. 题解: 首先我们从kmp的角度去考虑 这道题从字符串数据 ...

  9. bzoj 4503: 两个串【脑洞+FFT】

    真实脑洞题 因为通配符所以导致t串实际有指数级别个,任何字符串相关算法都没有用 考虑一个新的匹配方法:设a串(模板串)长为n,从m串的i位置开始匹配:\( \sum_{i=0}^{n-1}(a[j]- ...

随机推荐

  1. 51 Nod 1119

    机器人走方格 V2 M * N的方格,一个机器人从左上走到右下,只能向右或向下走.有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果. Input 第1行,2个数M,N ...

  2. linux基本命令学习02

    =============================================================================a.txtc:\abc\a.txt windo ...

  3. Mybatis之基于XML的表之间映射

    数据库表之间的关系有3种,一对一.一对多.多对多.既然是ORM,这肯定是必须有的.在学习EF的时候也有涉及,今天就是参考着EF的来学习下MyBatis的表关系映射. 一.准备工作 1.准备Model和 ...

  4. vue-cli脚手架的.babelrc文件 详解

    { // 此项指明,转码的规则 "presets": [ // env项是借助插件babel-preset-env,下面这个配置说的是babel对es6,es7,es8进行转码,并 ...

  5. electron 学习笔记

    一.快速搭建一个electron 项目结构 # 克隆示例项目的仓库 $ git clone https://github.com/electron/electron-quick-start # 进入这 ...

  6. PHP怎么获取系统信息和服务器详细信息

    https://zhidao.baidu.com/question/1435990326608475859.html 获取系统类型及版本号: php_uname() (例:Windows NT COM ...

  7. webpack模块机制浅析【一】

    webpack模块机制浅析[一] 今天看了看webpack打包后的代码,所以就去分析了下代码的运行机制. 下面这段代码是webpack打包后的最基本的形式,可以说是[骨架] (function(roo ...

  8. python判断两个list包含关系

    a = [1,2] b = [1,2,3] c = [0, 1] set(b) > set(a) set(b) > set(c)

  9. Spring-事务配置和详解

    一.Spring事务配置 在项目开发过程中经常会使用事务来确保数据的一致性.根据网上的资料整理一下在spring中配置事务的几种方式.无论是哪种方式都需要在配置文件中配置连接池和事务管理器,代码如下. ...

  10. lambda高级进阶--表达式参数

    1,现在我们封装一个方法,来提供一个比较器,显然比较器是拥有两个参数的--用来比较的两个值. public class Linkin { public static String[] sort(Str ...