zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    习题解答chapter-01
    Java-chapter-01 菜鸟初见Java
    ijkdemo
    1027
    avformat_seek_file
    pla
    android1010横屏等
    文件浏览对话框
    智能指针处理---bo
    Js为Dom元素绑定事件须知
  • 原文地址:https://www.cnblogs.com/olinr/p/10586790.html
Copyright © 2011-2022 走看看