【题目大意】

双串带通配符匹配。

$|S|, |T| \leq 5 * 10^5$

TL: 2s

【题解】

参考bzoj 4503

可以设计如下函数 A[i] * B[i] * (A[i] - B[i])^2

如果有通配符,A[i] = 0,否则,A[i] = s[i] - 'a' + 1;B同理。

可以自行验证,这是一种很妙的设计。

然后就是卷积的事情了。大概做9次DFT。

可以用类似于MTT的技巧搞到4次,不会写。

# include <math.h>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + , N = 2e6 + ;
const int mod = 1e9+;
const ld pi = acos(-1.0); char s[M], t[M];
int A[M], B[M], ns, nt; struct cp {
ld x, y;
cp() {}
cp(ld x, ld y) : x(x), y(y) {}
friend cp operator + (cp a, cp b) {
return cp(a.x + b.x, a.y + b.y);
}
friend cp operator - (cp a, cp b) {
return cp(a.x - b.x, a.y - b.y);
}
friend cp operator * (cp a, cp b) {
return cp(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
}
}a[N], b[N], ans[N]; namespace FFT {
int n, lst[N]; cp w[][N];
inline void set(int _n) {
n = ;
while(n < _n) n <<= ;
for (int i=; i<n; ++i) w[][i] = cp(cos(pi * / n * i), sin(pi * / n * i)), w[][i] = cp(w[][i].x, -w[][i].y);
int len = ;
while((<<len) < n) ++len;
for (int i=; i<n; ++i) {
int t = ;
for (int j=; j<len; ++j) if(i & (<<j)) t |= (<<(len-j-));
lst[i] = t;
}
}
inline void DFT(cp *a, int op) {
cp *o = w[op];
for (int i=; i<n; ++i) if(i < lst[i]) swap(a[i], a[lst[i]]);
for (int len=; len<=n; len<<=) {
int m = len>>;
for (cp *p=a; p!=a+n; p+=len) {
for (int k=; k<m; ++k) {
cp t = o[n/len*k] * p[k+m];
p[k+m] = p[k] - t;
p[k] = p[k] + t;
}
}
}
if(op) {
for (int i=; i<n; ++i) a[i].x /= (ld)n, a[i].y /= (ld)n;
}
}
} # define L FFT::n int main() {
scanf("%s%s", t, s); ns = strlen(s), nt = strlen(t);
for (int i=; i<ns; ++i) A[i] = (s[i] == '*' ? : s[i] - 'a' + );
for (int i=; i<nt; ++i) B[i] = (t[i] == '*' ? : t[i] - 'a' + );
reverse(B, B+nt);
// (A[i] - B[i])^2 * A[i] * B[i] = A[i]^3 * B[i] + A[i] * B[i]^3 - A[i]^2 * B[i]^2
FFT :: set(max(ns, nt));
for (int i=; i<ns; ++i) a[i] = cp(A[i] * A[i] * A[i], );
for (int i=ns; i<L; ++i) a[i] = cp(, );
for (int i=; i<nt; ++i) b[i] = cp(B[i], );
for (int i=nt; i<L; ++i) b[i] = cp(, );
FFT :: DFT(a, ); FFT :: DFT(b, );
for (int i=; i<L; ++i) ans[i] = ans[i] + a[i] * b[i];
for (int i=; i<ns; ++i) a[i] = cp(A[i], );
for (int i=ns; i<L; ++i) a[i] = cp(, );
for (int i=; i<nt; ++i) b[i] = cp(B[i] * B[i] * B[i], );
for (int i=nt; i<L; ++i) b[i] = cp(, );
FFT :: DFT(a, ); FFT :: DFT(b, );
for (int i=; i<L; ++i) ans[i] = ans[i] + a[i] * b[i];
for (int i=; i<ns; ++i) a[i] = cp(A[i] * A[i] * , );
for (int i=ns; i<L; ++i) a[i] = cp(, );
for (int i=; i<nt; ++i) b[i] = cp(B[i] * B[i], );
for (int i=nt; i<L; ++i) b[i] = cp(, );
FFT :: DFT(a, ); FFT :: DFT(b, );
for (int i=; i<L; ++i) ans[i] = ans[i] - a[i] * b[i];
FFT :: DFT(ans, );
for (int i=nt-; i<ns; ++i) {
if((int)(ans[i].x-0.5) == ) printf("%d ", i-nt+);
}
puts("");
return ;
}

可能是noi前最后一次复习FFT了。

省队集训 Day1 残缺的字符串的更多相关文章

  1. FJ省队集训DAY1 T1

    题意:有一堆兔子,还有一个r为半径的圆,要求找到最大集合满足这个集合里的兔子两两连边的直线不经过圆. 思路:发现如果有两个点之间连边不经过圆,那么他们到圆的切线会构成一段区间,那么这两个点的区间一定会 ...

  2. 省队集训Day1 过河

    [题目大意] 小奇特别喜欢猪,于是他养了$n$只可爱的猪,但这些猪被魔法猪教会了魔法,一不看着某些猪就会自己打起来. 小奇要带着他的猪讨伐战狂,路途中遇到了一条河.小奇找到了一条船,可惜这条船一次只能 ...

  3. 省队集训Day1 睡觉困难综合征

    传送门:https://www.luogu.org/problem/show?pid=3613 [题解] 按二进制位分开,对于每一位,用“起床困难综合征”的方法贪心做. 写棵LCT,维护正反两种权值, ...

  4. 省队集训Day1 总统选举

    [题目大意] 一个$n$个数的序列,$m$次操作,每次选择一段区间$[l, r]$,求出$[l, r]$中出现超过一半的数. 如果没有超过一半的数,那么就把答案钦定为$s$,每次会有$k$个数进行改变 ...

  5. HN2018省队集训

    HN2018省队集训 Day1 今天的题目来自于雅礼的高二学长\(dy0607\). 压缩包下载 密码: 27n7 流水账 震惊!穿着该校校服竟然在四大名校畅通无阻?霸主地位已定? \(7:10\)从 ...

  6. 【欧拉回路+最小生成树】SD开车@山东2018省队一轮集训day1

    目录 [欧拉回路+最小生成树]SD开车@山东2018省队一轮集训day1 PROBLEM 题目描述 输入 输出 样例输入 样例输出 提示 SOLUTION CODE [欧拉回路+最小生成树]SD开车@ ...

  7. [Luogu P4143] 采集矿石 [2018HN省队集训D5T3] 望乡台platform

    [Luogu P4143] 采集矿石 [2018HN省队集训D5T3] 望乡台platform 题意 给定一个小写字母构成的字符串, 每个字符有一个非负权值. 输出所有满足权值和等于这个子串在所有本质 ...

  8. JS省队集训记

    不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...

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

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

随机推荐

  1. PAT1024 强行用链表写了一发。

    主要的思想还是 上课的那个PPT上面的 链表反转的思想. 然后加一点七七八八的 递推. 一层一层往下翻转就好啦. 1A 真开心. 代码:http://paste.ubuntu.net/16506799 ...

  2. hashMap原理(java8)

    (1) HashMap:它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的. HashMap最多只允许一条记录的键为null,允许多 ...

  3. 二叉树及其遍历方法---python实现

    github:代码实现 本文算法均使用python3实现 1. 二叉树 1.1 二叉树的定义   二叉树是一种特殊的树,它具有以下特点:   (1)树中每个节点最多只能有两棵树,即每个节点的度最多为2 ...

  4. 转 Redis集群技术及Codis实践

    转  Redis集群技术及Codis实践 转自 :http://blog.51cto.com/navyaijm/1637688 codis开源地址:https://github.com/CodisLa ...

  5. YaoLingJump开发者日志(五)V1.0版本完成

    跳跃吧瑶玲下载连接 官网下载 百度网盘下载 提取码:apx9 介绍   总算完成V1.0版本了,下面来简单地介绍一下吧!   打开游戏,最开始会进入到"主界面".   右上角的按钮 ...

  6. 重要的几个按键Tab Ctrl+c Ctrl+d

    1.Tab按键具有命令补齐和档案补齐的功能,重点是可以避免我们打错命令或者文件名,但是Tab按键在不同的地方输入会有不同的结果 试着多按几下,或者连按两次相信你会发现新大陆 a.Tab接在一串指令的第 ...

  7. vc6.0批量加注释

    MATLAB批量加注释的方法非常简单明了,加注释是ctrl+R,去注释是ctrl+T 然后在VC中我对一条一条加注释的方法非常烦恼,我想也许会有简单的方法可以批量家注释.果然,先贴代码 '------ ...

  8. [计算机网络] DNS何时使用TCP协议,何时使用UDP协议

    DNS同时占用UDP和TCP端口53是公认的,这种单个应用协议同时使用两种传输协议的情况在TCP/IP栈也算是个另类.但很少有人知道DNS分别在什么情况下使用这两种协议. 先简单介绍下TCP与UDP. ...

  9. html5 js canvas中画星星的函数

    function drawStar(cxt, x, y, outerR, innerR, rot) { cxt.beginPath(); ; i < ; i++) { cxt.lineTo(Ma ...

  10. java计算某日期之后的日期

    public static void main(String[] args) { // 时间表示格式可以改变,yyyyMMdd需要写例如20160523这种形式的时间 SimpleDateFormat ...