码迷,mamicode.com
首页 > 其他好文 > 详细

P4717 【模板】快速沃尔什变换

时间:2019-03-24 09:59:58      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:class   序列   etc   ==   bit   tchar   输入   getch   数据   

$ \color{#0066ff}{ 题目描述 }$

给定长度为\(2^n\)两个序列\(A,B\),设\(C_i=\sum_{j\oplus 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}\)的值\(\bmod\ 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? '\n' : ' ');
}

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? '\n' : ' ');
}
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? '\n' : ' ');
}
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 【模板】快速沃尔什变换

标签:class   序列   etc   ==   bit   tchar   输入   getch   数据   

原文地址:https://www.cnblogs.com/olinr/p/10586790.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!