【题目大意】

双串带通配符匹配。

$|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. python异步初步窥探

    1.异步之难:因为其执行吮吸不可预料,当下正要发生什么事件不可预料.        程序下一步行为往往依赖上一步值执行结果,如何知晓上次异步调用已完成并获取结果,        回调成了必然选择,那又 ...

  2. TCP系列30—窗口管理&流控—4、Cork算法

    一.Cork算法概述 Cork算法与Nagle算法类似,也有人把Cork算法称呼为super-Nagle.Nagle算法提出的背景是网络因为大量小包小包而导致利用率低下产生网络拥塞,网络发生拥塞的时候 ...

  3. 3ds Max学习日记(七)

      第7章讲的是多边形建模,实例略多,有十六个,再加上周日的怠惰感,只做了几个实例. 附上今日的劳动成果:   布料(创建一个平面,转换为可编辑多边形,然后调整顶点,连接一些边,添加网格平滑,转换为可 ...

  4. thinkphp5学习记录一

    1 使用composer安装 composer create-project topthink/think=5.0.* tpblog --prefer-dist 2 配置环境vim /usr/loca ...

  5. python爬虫从入门到放弃(四)之 Requests库的基本使用(转)

    什么是Requests Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库如果你看过上篇文章关于urllib库的使用,你会发现,其 ...

  6. 【Linux】- netstat 命令

    Linux netstat命令用于显示网络状态.利用netstat指令可让你得知整个Linux系统的网络情况. 语法 netstat [-acCeFghilMnNoprstuvVwx][-A<网 ...

  7. 简单名称值对节点类NameValuePair

    本类位于System.Data.dll中,名为:System.Data.Common.NameValuePair.主要用途是在DBConnectionString类中,解析ConnectionStri ...

  8. C#下载网页

    System.Net.WebClient wc = new System.Net.WebClient(); Byte[] pageData = wc.DownloadData("网页地址&q ...

  9. Qt快速入门学习笔记(画图篇)

    1.Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于QPainter.QPaintDevice和QPaintEngine这三个类.其中QPainter用来执行 ...

  10. zoj3209-Treasure Map

    给出一个左下角为\((0,0)\),右上角为\((n,m)\)的矩形,再给出\(k\)个在大矩形内的小矩形(可以重合),问是否能用这些小矩形完全覆盖这个大矩形,并且没有重合,如果可以至少需要多少个. ...