题目链接:P4173 残缺的字符串

题意

给定长度为 \(m\) 的模式串和长度为 \(n\) 的目标串,两个串都带有通配符,求所有匹配的位置。

思路

FFT

带有通配符的字符串匹配问题。

设模式串为 \(p\),目标串为 \(t\),将两个串的内容都根据字母先后顺序映射到 \(1\) 到 \(26\)。

如果不带有通配符,那么 \(t\) 以第 \(k\) 位结束的长度为 \(|p|\) 的子串与 \(p\) 匹配时有

\[\sum_{i=0}^{|p|-1} (p[i] - t[k - |p| + 1 + i])^2 = 0\]

如果带有通配符,只需将上式稍微改一下就行。

让两个串中的所有通配符映射到 \(0\),设匹配结果为 \(f\),则有

\[f[i] = \sum_{i=0}^{|p|-1} (p[i] - t[k - |p| + 1 + i])^2 \cdot p[i] \cdot t[k - |p| + 1 + i]\]

接下来翻转 \(p\) 串 (\(FFT\) 的套路),设 \(r[|p| - i - 1] = p[i]\),则有

\[f[i] = \sum_{i=0}^{|p|-1} (r[|p| - i - 1] - t[k - |p| + 1 + i])^2 \cdot r[|p| - i - 1] \cdot t[k - |p| + 1 + i]\]

下标加起来等于 \(k\),令 \(j = |p| - i - 1\),则

\[f[i] = \sum_{i + j = k} (r[j] - t[i])^2 \cdot r[j] \cdot t[i]\]

展开后有

\[f[i] = \sum_{i + j = k} (r[j]^3t[i] + t[i]^3r[j] - 2\cdot r[j]^2t[i]^2)\]

用 \(FFT\) 分别求一下卷积即可。

代码

#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1);
const double eps = 1e-8;
typedef complex<double> Complex;
const int maxn = 2e6 + 10;Complex p[maxn], t[maxn];
Complex a[maxn], b[maxn], c[maxn], d[maxn];
Complex ans[maxn];
string str;
int m, n;
int bit = 2, rev[maxn];void get_rev(){memset(rev, 0, sizeof(rev));while(bit <= n + m) bit <<= 1;for(int i = 0; i < bit; ++i) {rev[i] = (rev[i >> 1] >> 1) | (bit >> 1) * (i & 1);}
}void FFT(Complex *a, int op) {for(int i = 0; i < bit; ++i) {if(i < rev[i]) swap(a[i], a[rev[i]]);}for(int mid = 1; mid < bit; mid <<= 1) {Complex wn = Complex(cos(PI / mid), op * sin(PI / mid));for(int j = 0; j < bit; j += mid<<1) {Complex w(1, 0);for(int k = 0; k < mid; ++k, w = w * wn) {Complex x = a[j + k], y = w * a[j + k + mid];a[j + k] = x + y, a[j + k + mid] = x - y;}}}
}int main() {ios::sync_with_stdio(false);cin.tie(0);cin >> m >> n;cin >> str;for(int i = 0; i < m; ++i) {p[m - i - 1] = str[i] == '*' ? 0 : (str[i] - 'a' + 1);}cin >> str;for(int i = 0; i < n; ++i) {t[i] = str[i] == '*' ? 0 : (str[i] - 'a' + 1);}get_rev();for(int i = 0; i < bit; ++i) {a[i] = p[i] * p[i] * p[i];b[i] = t[i];}FFT(a, 1); FFT(b, 1);for(int i = 0; i < bit; ++i) {ans[i] += a[i] * b[i];}for(int i = 0; i < bit; ++i) {a[i] = p[i];b[i] = t[i] * t[i] * t[i];}FFT(a, 1); FFT(b, 1);for(int i = 0; i < bit; ++i) {ans[i] += a[i] * b[i];}for(int i = 0; i < bit; ++i) {a[i] = p[i] * p[i];b[i] = t[i] * t[i];}FFT(a, 1); FFT(b, 1);for(int i = 0; i < bit; ++i) {ans[i] -= a[i] * b[i] * Complex(2, 0);}FFT(ans, -1);queue<int> q;for(int i = m - 1; i < n; ++i) {if((int)(ans[i].real() / bit + 0.5) == 0) q.push(i - m + 2);}cout << q.size() << endl;while(q.size()) {cout << q.front() << " ";q.pop();}cout << endl;return 0;
}

转载于:https://www.cnblogs.com/wulitaotao/p/11575354.html

洛谷 P4173 残缺的字符串 (FFT)相关推荐

  1. 洛谷 - P4173 残缺的字符串(多项式匹配字符串-NTT)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串 sss 和一个长度为 mmm 的字符串 ttt,都含有通配符 '*',现在问字符串 ttt 可以匹配字符串 nnn 的哪些位置 题目分析 ...

  2. P4173 残缺的字符串 FFT匹配含有通配符的字符串

    传送门 文章目录 题意: 思路: 题意: 给你两个长度为m,nm,nm,n的串a,ba,ba,b,问你bbb串中每个长度为mmm的连续字串能否与aaa完全匹配,其中含有通配符∗*∗,输出每个位置的开头 ...

  3. P4173 残缺的字符串

    P4173 残缺的字符串 题意: 有A,B两个串,每个串都有通配符,问A为模板串,对于 B 的每一个位置 i,从这个位置开始连续 m 个字符形成的子串是否可能与 A 串完全匹配? 题解: 我们定义两个 ...

  4. BZOJ 4259: 残缺的字符串 [FFT]

    4259: 残缺的字符串 题意:s,t,星号任意字符,匹配方案数 和上题一样 多乘上一个\(a_{j+i}\)就行了 #include <iostream> #include <cs ...

  5. 洛谷P1852 奇怪的字符串

    题目描述 输入两个01串,输出它们的最长公共子序列的长度 输入输出格式 输入格式: 一行,两个01串 输出格式: 最长公共子序列的长度 输入输出样例 输入样例#1: 复制 01010101010 00 ...

  6. 洛谷P4173:残缺的字符串(FFT、通配符匹配)

    解析 通配符匹配的经典题. 设单词串为 AAA,文章串为 BBB. 把 AAA 翻转一下,判断问题就能转化为一个卷积的形式: F(p)=&i=0m−1match(Ai+1,Bp−i)F(p)= ...

  7. 【BZOJ】4259: 残缺的字符串 FFT

    [题意]给定长度为m的匹配串B和长度为n的模板串A,求B在A中出现多少次.字符串仅由小写字母和通配符" * "组成,其中通配符可以充当任意一个字符.n<=3*10^5. [算 ...

  8. 洛谷P4199 万径人踪灭(manacher+FFT)

    传送门 题目所求为所有的不连续回文子序列个数,可以转化为回文子序列数-回文子串数 回文子串manacher跑一跑就行了,考虑怎么求回文子序列数 我们考虑,如果$S_i$是回文子序列的对称中心,那么只要 ...

  9. 洛谷P3952 时间复杂度【字符串】【模拟】

    题目描述 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序 ...

  10. 洛谷P3338:力(FFT)

    传送门 解析 算是比较适合的FFT入门题了吧 一个重要的trick: 当函数无法表示成卷积时,可以把函数翻转过来 然后调一调就又是卷积了 一个重要的注意事项是FFT的lim一定是两多项式相乘结果多项式 ...

最新文章

  1. ASCII、Unicode、GBK和UTF-8字符编码的区别联系
  2. (pytorch-深度学习系列)pytorch卷积层与池化层输出的尺寸的计算公式详解
  3. python网课什么平台好-python网课什么平台好
  4. java 时间戳和PHP时间戳 的转换 php time()
  5. 阿里云开源PolarDB数据库,与社区共建云原生分布式数据库生态
  6. bzoj 1670 [Usaco2006 Oct]Building the Moat护城河的挖掘——凸包
  7. 第三次学JAVA再学不好就吃翔(part49)--String类的获取功能
  8. 基于IdentityServer的系统对接微信公众号
  9. VMware 克隆的相关设置
  10. ArrayList实现原理及源码分析之JDK8
  11. 主成分分析法怎么提取图片中的字_视频图像的MATLAB处理(2)两种主成分分析方法...
  12. 机器学习算法篇:最大似然估计证明最小二乘法合理性
  13. 简单图形验证码的识别
  14. CF736 D1 格点图,皮克定理
  15. 知识图谱指南:从理论到应用
  16. 源码解读ReDet:A Rotation-equivariant Detector for Aerial Object Detection
  17. 电气隔离 电源模块 升压/充电 实测案例 150V 30W 带四个220UF电解电容并联 300ms
  18. 关于java中getInstance()方法
  19. 一头扎紧mysql_[www.java1234.com]一头扎进Mysql视频教程
  20. 帝都计算机谱子,天谕手游你给我所有乐谱代码是什么-天谕手游你给我所有乐谱代码分享_快吧手游...

热门文章

  1. 固态硬盘用软件测试掉速严重,固态硬盘掉速别慌张,教你如何快速进行调节!...
  2. 计算机成绩英语翻译,本科成绩单翻译中英文对照
  3. 解决Linux系统下U盘只读文件系统问题
  4. 【平面几何】点线距离与位置关系
  5. lbp7660cdn设置网络打印_canonlbp7660cdn驱动下载-佳能lbp7660cdn打印机驱动v21.52 官方版 - 极光下载站...
  6. react-ssr之路由配置
  7. 紫猫插件-网络共享数据(1-6)
  8. 耗时两周,纯手敲python入门级基础笔记
  9. 想你的风还是吹到了长沙
  10. android图片尺寸大小设置