LG P4717 【模板】快速莫比乌斯/沃尔什变换 (FMT/FWT)
2024-09-08 18:36:14
\[C_k = \sum_{i|j=k}A_i B_j
\]
\]
这样的或卷积可以做一次 \(\text{FWT}\),把数组变为 \(\widehat{A}_i = \sum_{j\subseteq i}A_i\),也就是子集和的形式,然后就可以对应位相乘了
变回去的话就减掉之前加上来的贡献
与卷积,异或卷积同理
如果异或卷积只要求某一特定的次数 \(i\) 的系数,那么有 \([x^i]\widehat{A} = \sum_j [x^j]A \cdot {(-1)}^{\text{popcount(i&j)}}\)
而逆回去的话照上面的式子只要再多乘个 \(\frac1{2^{len}}\) 即可
$\text{Code}$
#include <cstdio>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define IN inline
using namespace std;
template <typename T>
IN void read(T &x) {
x = 0; char ch = getchar(); int f = 0;
for(; !isdigit(ch); f = (ch == '-' ? 1 : f), ch = getchar());
for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar());
if (f) x = ~x + 1;
}
typedef long long LL;
const int N = 2e5 + 5, P = 998244353, inv2 = (P + 1) >> 1;
int A[N], B[N], a[N], b[N], n;
IN void init(){for(int i = 0; i < n; i++) a[i] = A[i], b[i] = B[i];}
IN void print(){for(int i = 0; i < n; i++) printf("%d ", a[i]); puts("");}
IN void mul(){for(int i = 0; i < n; i++) a[i] = (LL)a[i] * b[i] % P;}
IN void FWT_or(int *a, int op) {
for(int mid = 1; mid < n; mid <<= 1)
for(int i = 0; i < n; i += (mid << 1))
for(int j = 0; j < mid; ++j)
(a[i + j + mid] += (LL)a[i + j] * op % P) %= P;
}
IN void FWT_and(int *a, int op) {
for(int mid = 1; mid < n; mid <<= 1)
for(int i = 0; i < n; i += (mid << 1))
for(int j = 0; j < mid; ++j)
(a[i + j] += (LL)a[i + j + mid] * op % P) %= P;
}
IN void FWT_xor(int *a, int op) {
for(int mid = 1; mid < n; mid <<= 1)
for(int i = 0; i < n; i += (mid << 1))
for(int j = 0; j < mid; ++j) {
int x = a[i + j], y = a[i + j + mid];
a[i + j] = (LL)(x + y) * op % P,
a[i + j + mid] = (LL)(x - y + P) * op % P;
}
}
int main() {
read(n), n = 1 << n;
for(int i = 0; i < n; ++i) read(A[i]);
for(int i = 0; i < n; ++i) read(B[i]);
init(), FWT_or(a, 1), FWT_or(b, 1), mul(), FWT_or(a, P - 1), print();
init(), FWT_and(a, 1), FWT_and(b, 1), mul(), FWT_and(a, P - 1), print();
init(), FWT_xor(a, 1), FWT_xor(b, 1), mul(), FWT_xor(a, inv2), print();
}
最新文章
- 【NLP】揭秘马尔可夫模型神秘面纱系列文章(四)
- 分布式开放消息系统(RocketMQ)的原理与实践
- selenium设置Chrome
- 【Python自动化运维之路Day6】
- noip2014普及组 比例简化
- Android(java)学习笔记106-1:深入分析Java ClassLoader原理
- require backbone 移动
- JAVA bean与XML互转的利器---XStream
- DES加密系统的实现
- VS2012破解_序列号
- MVC运行机制
- linux通配符与正则表达式
- shell脚本基础1 概述及变量
- C# 动态调用WebService 3
- 3.docker基础架构
- Android逆向基础----Android Dalvik虚拟机
- linux源码安装服务器所需要的一些依赖库(待完善)
- C#集合类型大揭秘
- 启动与关闭WebService
- 使用copydata实现进程之间数据传递