【洛谷P4173】残缺的字符串
题目大意:给定一个文本串和一个模板串,串中含有通配符,求文本串中有多少个位置可以与文本串完全匹配。
题解:利用卷积求解字符串匹配问题。
通配符字符串匹配的数值表示为 $$\sum\limits_{i = 0}^{m - 1}(a[i] - b[i + k])^2 a[i]b[i + k]=0$$。直接展开之后计算三个卷积即可。
需要注意的是:并不是所有 a[i] b[i + k] 均为循环卷积,是否需要倍增取决于是否成环。
代码如下
#include <bits/stdc++.h>
using namespace std;
typedef complex<double> cp;
const double eps = 1e-8;
const double pi = acos(-1);
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> m >> n;
string s, t;
cin >> t >> s;
int tot = 1, bit = 0;
while (tot <= n + m) {
tot <<= 1;
++bit;
}
vector<int> rev(tot);
for (int i = 0; i < tot; i++) {
rev[i] = rev[i >> 1] >> 1 | (i & 1) << bit - 1;
}
vector<cp> a1(tot), a2(tot), a3(tot), b1(tot), b2(tot), b3(tot);
auto work = [](char ch) {
if (ch == '*') {
return 0;
} else {
return ch - 'a' + 1;
}
};
for (int i = 0; i < m; i++) {
int x = work(t[i]);
a1[m - 1 - i] = x;
a2[m - 1 - i] = x * x;
a3[m - 1 - i] = x * x * x;
}
for (int i = 0; i < n; i++) {
int x = work(s[i]);
b1[i] = x;
b2[i] = x * x;
b3[i] = x * x * x;
}
auto fft = [=](vector<cp> &v, int opt) {
for (int i = 0; i < tot; i++) {
if (i < rev[i]) {
swap(v[i], v[rev[i]]);
}
}
for (int mid = 1; mid < tot; mid <<= 1) {
cp wn(cos(pi / mid), opt * sin(pi / mid));
for (int j = 0; j < tot; j += mid << 1) {
cp w(1, 0);
for (int k = 0; k < mid; k++) {
cp x = v[j + k], y = w * v[j + mid + k];
v[j + k] = x + y, v[j + mid + k] = x - y;
w *= wn;
}
}
}
if (opt == -1) {
for (int i = 0; i < tot; i++) {
v[i].real(round(v[i].real() / tot));
}
}
};
auto calc = [=](vector<cp> &a, vector<cp> &b) {
fft(a, 1), fft(b, 1);
for (int i = 0; i < tot; i++) {
a[i] *= b[i];
}
fft(a, -1);
};
calc(a3, b1), calc(a2, b2), calc(a1, b3);
int ans = 0;
vector<int> pos;
for (int k = 0; k < n - m + 1; k++) {
double ret = a3[m + k - 1].real() - 2 * a2[m + k - 1].real() + a1[m + k - 1].real();
if (fabs(ret) < eps) {
++ans;
pos.push_back(k + 1);
}
}
cout << ans << endl;
for (auto p : pos) {
cout << p << " ";
}
return 0;
}
【洛谷P4173】残缺的字符串的更多相关文章
- 洛谷 P4173 残缺的字符串 (FFT)
题目链接:P4173 残缺的字符串 题意 给定长度为 \(m\) 的模式串和长度为 \(n\) 的目标串,两个串都带有通配符,求所有匹配的位置. 思路 FFT 带有通配符的字符串匹配问题. 设模式串为 ...
- 洛谷P4173 残缺的字符串(FFT)
传送门 话说为什么字符串会和卷积扯上关系呢……到底得脑洞大到什么程度才能想到这种东西啊……大佬太珂怕了…… 因为通配符的关系,自动机已经废了 那么换种方式考虑,如果两个字符串每一位对应的编码都相等,那 ...
- 洛谷P4173 残缺的字符串
题目大意: 两个带通配符的字符串\(a,b\),求\(a\)在\(b\)中出现的位置 字符串长度\(\le 300000\) 考虑魔改一发\(kmp\),发现魔改不出来 于是考虑上网搜题解 然后考虑\ ...
- 洛谷 P4173 残缺的字符串
(不知道xjb KMP可不可以做的说) (假设下标都以0开头) 对于有一定偏移量的序列的 对应位置 匹配或者数值计算的题,这里是有一种套路的,就是把其中一个序列翻转过来,然后卷积一下,所得到的新序列C ...
- Luogu P4173 残缺的字符串-FFT在字符串匹配中的应用
P4173 残缺的字符串 FFT在字符串匹配中的应用. 能解决大概这种问题: 给定长度为\(m\)的A串,长度为\(n\)的B串.问A串在B串中的匹配数 我们设一个函数(下标从\(0\)开始) \(C ...
- P4173 残缺的字符串(FFT字符串匹配)
P4173 残缺的字符串(FFT字符串匹配) P4173 解题思路: 经典套路将模式串翻转,将*设为0,设以目标串的x位置匹配结束的匹配函数为\(P(x)=\sum^{m-1}_{i=0}[A(m-1 ...
- BZOJ1856或洛谷1641 [SCOI2010]生成字符串
BZOJ原题链接 洛谷原题链接 可以将\(1\)和\(0\)的个数和看成是\(x\)轴坐标,个数差看成\(y\)轴坐标. 向右上角走,即\(x\)轴坐标\(+1\),\(y\)轴坐标\(+1\),表示 ...
- 卡特兰数 洛谷P1641 [SCOI2010]生成字符串
卡特兰数 参考博客 介绍 卡特兰数为组合数学中的一种特殊数列,用于解决一类特殊问题 设\(f(n)\)为卡特兰数的第n项 其通项公式为 \[f(n)=\frac{2n\choose n}{n+1} \ ...
- 洛谷 P1641 [SCOI2010]生成字符串
洛谷 这题一看就是卡塔兰数. 因为\(cnt[1] \leq cnt[0]\),很显然的卡塔兰嘛! 平时我们推导卡塔兰是用一个边长为n的正方形推的, 相当于从(0,0)点走到(n,n)点,向上走的步数 ...
- 洛谷P1852 奇怪的字符串
题目描述 输入两个01串,输出它们的最长公共子序列的长度 输入输出格式 输入格式: 一行,两个01串 输出格式: 最长公共子序列的长度 输入输出样例 输入样例#1: 复制 01010101010 00 ...
随机推荐
- Python爬虫学习==>第七章:urllib库的基本使用方法
学习目的: urllib提供了url解析函数,所以需要学习正式步骤 Step1:什么是urllib urllib库是Python自带模块,是Python内置的HTTP请求库 包含4个模块: >& ...
- windows使用放大镜快速放大屏幕局部
Win10系统自带放大镜有时真的是比较难使用的,但是如果你对他的快捷键有所了解之后就会感觉它其实也没有那么难,用户可以在使用完之后直接按快捷键将其关闭,一起看看吧. Win10系统放大镜快速关闭快捷键 ...
- Java中流的操作练习
文件中的学生信息 学生信息存储在TXT文件中,我们需要对信息进行基本的,增.删.改.查,全部显示操作. 1.学生类/Student package com.yujiao.student; public ...
- [c++] 链表各类操作详解
链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称 ...
- 面向对象编程 OOP
OOP,Object Oriented Programming,原来就是面向对象的编程. 面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物. OOD,Object Or ...
- P2670 【扫雷游戏】
题面哦~~ lalala~~~ 这题数据并不大,最大不过100*100,所以果断穷举 其实本来我是想边读边做的,但读入是个问题. 主要思路呢,就是读完之后穷举一边,只要是炸弹,就把周围一圈8个加一遍 ...
- python_0基础开始_day12
第十二节 一,生成器 生成器的核心:生成器的本质就是迭代器 迭代器是python自带的 生成器是程序员自己写的一种迭代器 在python中有三种方式来创建生成器: 基于函数编写 推导式方式编写 pyt ...
- linux端口控制(开放-禁止)
禁止访问80端口iptables -I INPUT -p tcp --dport 80 -j DROP 允许ip为192.168.1.1的机器访问iptables -I INPUT -p tcp -s ...
- Mysql 备份数据库方法及when using LOCK TABLES错误解决方法
可以将以下代码保存为backup.bat,添加计划任务即可. @echo off ,,%" ,%" "D: -uname -pxxxx -P3306 --skip-loc ...
- git 基础命令 学习总结
首先介绍一个git 里工作流的概念: 你的本地仓库由 git 维护的三棵“树”组成.第一个是你的 工作目录,它持有实际文件:第二个是 缓存区(Index),它像个缓存区域,临时保存你的改动:最后是 H ...