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. A Bug's Life(种类并查集)(也是可以用dfs做)

    http://acm.hdu.edu.cn/showproblem.php?pid=1829   A Bug's Life Time Limit:5000MS     Memory Limit:327 ...

  2. 如何检测浏览器url变化

    用户通过“点击触发”,“操作历史”,“直接访问URL”的方式修改当前URL.这三种触发方式会使浏览器做出不同的行为 html5提供了两种方式在页面中操作历史 history.pushState(sta ...

  3. CentOS 6.*通过yum安装 MySQL-5.5

    转自https://www.cnblogs.com/wsl222000/p/5445768.html 1.安装mysql-5.5的yum源 rpm -ivh http://repo.mysql.com ...

  4. 微信公众平台宣布增加接口IP白名单提高安全性

    微信公众平台目前已经发布通知在平台接口调用上为了提高安全性需要添加IP白名单并仅允许白名单IP调用. 目前微信公众平台面向开发者主要提供的开发者ID和开发者密钥,在调用时ID和密钥通过检验即可进行调用 ...

  5. PhpStorm常用的一些快捷键

    Ctrl + G  :  跳到当前打开文件的行,输入格式(行数:列数)Ctrl + E  : 打开最近编辑的文件列表Ctrl + P  : 显示函数的参数信息Ctrl + Q  : 快速打开函数的说明 ...

  6. 织梦在服务器上面安装的时候一直提示data文件没有权限,可我已经写了权限,还是提示

    1.进入服务器,打开IIS,点击相应无权限的文件夹data,然后点击右上角的编辑权限. 2.勾选写入,然后确定即可. 3.织梦一直收到黑客的攻击,这里建议站长朋友设置下权限,来降低织梦系统的危险系数. ...

  7. 常用SQL笔记总结

    DDL(data definition language)创建和管理表 1.创建表 1.直接创建 例如: create table emp( name varchar(20), salary int ...

  8. asp.net -mvc框架复习(10)-基于三层架构与MVC搭建项目框架

    一.三种模式比较 1.MVC框架(适合大型项目) (1).V视图 (网页部分) (2).M模型 (业务逻辑+数据访问+实体类) (3).C控制器 (介于M和V之间,起到引导作用) 2.三层架构 (1) ...

  9. JS-输入金额校验

    function clearNoNum(obj){    obj.value = obj.value.replace(/[^\d.]/g,"");  //清除"数字&qu ...

  10. 【Java框架型项目从入门到装逼】第十二节 项目分层

    这一节我们开始对项目进行分层,一般来说,一个web项目的层次结构如下图所示: controller层为我们的控制层,用来接收用户的请求,比如新增一个学生的信息,新增的请求最先就是走到这一层.contr ...