P4717 模板快速沃尔什变换
Posted olinr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4717 模板快速沃尔什变换相关的知识,希望对你有一定的参考价值。
$ color{#0066ff}{ 题目描述 }$
给定长度为(2^n)两个序列(A,B),设(C_i=sum_{joplus k}A_jB_k)
分别当(oplus)是or,and,xor时求出C
(color{#0066ff}{输入格式})
第一行一个数n。
第二行(2^n)个数(A_0..A_{2^n-1})
第三行(2^n)个数(B_0..B_{2^n-1})
(color{#0066ff}{输出格式})
三行每行(2^n)个数,分别代表(oplus)是or,and,xor时(C_0..C_{2^n-1})的值(mod 998244353)
(color{#0066ff}{输入样例})
2
2 4 6 8
1 3 5 7
(color{#0066ff}{输出样例})
2 22 46 250
88 64 112 56
100 92 68 60
(color{#0066ff}{数据范围与提示})
n≤17。
(color{#0066ff}{题解})
背公式qwq
FWTor
[ A[i+l+k]+=A[i+k] ]
IFWTor
[ A[i+l+k]-=A[i+k] ]
FWTand
[ A[i+k]+=A[i+l+k] ]
IFWTand
[ A[i+k]-=A[i+l+k] ]
FWTxor
[ A[i+k]=A[i+k]+A[i+l+k] \ A[i+k+l]=A[i+k]-A[i+l+k] ]
IFWTxor
[ A[i+k]=frac{A[i+k]+A[i+l+k]}{2} \ A[i+k+l]=frac{A[i+k]-A[i+l+k]}{2} ]
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 1e6 + 10;
const int mod = 998244353;
const int inv = 499122177;
int a[maxn], b[maxn], c[maxn], len;
void FWTor(int *A, int flag) {
for(int l = 1; l < len; l <<= 1)
for(int i = 0; i < len; i += (l << 1))
for(int k = 0; k < l; k++)
(A[i + l + k] += ((flag * A[i + k]) % mod + mod) % mod) %= mod;
}
void FWTand(int *A, int flag) {
for(int l = 1; l < len; l <<= 1)
for(int i = 0; i < len; i += (l << 1))
for(int k = 0; k < l; k++)
(A[i + k] += ((flag * A[i + l + k]) % mod + mod) % mod) %= mod;
}
void FWTxor(int *A, int flag) {
for(int l = 1; l < len; l <<= 1)
for(int i = 0; i < len; i += (l << 1))
for(int k = 0; k < l; k++) {
int tmp = A[i + k];
A[i + k] = 1LL * (tmp + A[i + l + k]) % mod * inv % mod * flag % mod;
A[i + l + k] = 1LL * ((tmp - A[i + l + k]) % mod + mod) % mod * inv % mod * flag % mod;
}
}
void workor() {
FWTor(a, 1), FWTor(b, 1);
for(int i = 0; i < len; i++) c[i] = 1LL * a[i] * b[i] % mod;
FWTor(a, -1), FWTor(b, -1), FWTor(c, -1);
for(int i = 0; i < len; i++) printf("%d%c", c[i], i + 1 == len? '
' : ' ');
}
void workand() {
FWTand(a, 1), FWTand(b, 1);
for(int i = 0; i < len; i++) c[i] = 1LL * a[i] * b[i] % mod;
FWTand(a, -1), FWTand(b, -1), FWTand(c, -1);
for(int i = 0; i < len; i++) printf("%d%c", c[i], i + 1 == len? '
' : ' ');
}
void workxor() {
FWTxor(a, 2), FWTxor(b, 2);
for(int i = 0; i < len; i++) c[i] = 1LL * a[i] * b[i] % mod;
FWTxor(a, 1), FWTxor(b, 1), FWTxor(c, 1);
for(int i = 0; i < len; i++) printf("%d%c", c[i], i + 1 == len? '
' : ' ');
}
int main() {
len = 1 << in();
for(int i = 0; i < len; i++) a[i] = in();
for(int i = 0; i < len; i++) b[i] = in();
workor();
workand();
workxor();
return 0;
}
以上是关于P4717 模板快速沃尔什变换的主要内容,如果未能解决你的问题,请参考以下文章