首页 > 其他分享 >快速沃尔什变换(FWT)

快速沃尔什变换(FWT)

时间:2024-11-06 20:21:05浏览次数:3  
标签:circ 变换 sum len int 沃尔什 FWT operatorname

快速沃尔什变换(FWT)

前言

本文为个人学习笔记,大量参考了 oi-wiki 以及其他博客的内容。

问题

给定 \(a, b\) 序列,求:

\[c_i = \sum_{i = j \oplus k} a_j b_k \]

其中,\(\oplus = \operatorname{or} / \operatorname{and} / \operatorname{xor}\)。

做法

核心思想

对于某种特定的 \(\oplus\),找到序列 \(FWT_a, FWT_b, FWT_c\) 分别对应序列 \(a, b, c\),需要满足以下性质和要求:

1、\(FWT_{c_i} = FWT_{a_i} \cdot FWT_{b_i}\);

2、需要在优秀的时间复杂度内进行 \(a\) 和 \(FWT_a\) 的变换。

下面一个一个符号来。

\(\operatorname{or}\)

\[FWT_{a_i} = \sum_{j, j | i = i} a_j \\ FWT_{a_i} \cdot FWT_{b_i} = \sum_{j, j | i = i} a_j \cdot \sum_{k, k | i = i} b_j = \sum_{j, k, (j | k) | i = i} (a_jb_k) = FWT_{c_i} \]

考虑 \(a\) 和 \(FWT_a\) 的变换,考虑分治处理,写出如下形式(\(a_0, a_1, a_2, a_3, a_4, a_5, a_6, a_7\)):

轮数 长度 \(FWT_0\) \(FWT_1\) \(FWT_2\) \(FWT_3\) \(FWT_4\) \(FWT_5\) \(FWT_6\) \(FWT_7\)
1 1 \(a_0\) \(a_1\) \(a_2\) \(a_3\) \(a_4\) \(a_5\) \(a_6\) \(a_7\)
2 2 \(a_0\) \(a_0 + a_1\) \(a_2\) \(a_2 + a_3\) \(a_4\) \(a_4 + a_5\) \(a_6\) \(a_6 + a_7\)
3 4 \(a_0\) \(a_0 + a_1\) \(a_0 + a_2\) \(a_0 + a_1 + a_2 + a_3\) \(a_4\) \(a_4 + a_5\) \(a_4 + a_6\) \(a_4 + a_5 + a_6 + a_7\)
4 8 \(a_0\) \(a_0 + a_1\) \(a_0 + a_2\) \(a_0 + a_1 + a_2 + a_3\) \(a_0 + a_4\) \(a_0 + a_1 + a_4 + a_5\) \(a_0 + a_2 + a_4 + a_6\) \(a_0 + a_1 + a_2 + a_3 + \\ a_4 + a_5 + a_6 + a_7\)

容易写出以下代码,

inline void FWT_OR(int *A) {
    for (int len = 2; len <= (1 << n); len *= 2)
        for (int x = 0; x < (1 << n); x += len)
            for (int i = x; i < x + len / 2; ++ i)
                A[i + len / 2] = (A[i] + A[i + len / 2]) % mod;
}

对于 \(FWT_a\) 变换为 \(a\),反着把 \(FWT_a\) 数组转化为 \(a\) 数组即可。

inline void IFWT_OR(int *A) {
    for (int len = (1 << n); len >= 2; len /= 2)
        for (int x = 0; x < (1 << n); x += len)
            for (int i = x; i < x + len / 2; ++ i)
                A[i + len / 2] = (A[i + len / 2] - A[i]) % mod;
}

\(\operatorname{and}\)

\[FWT_{a_i} = \sum_{j, j \& i = i} a_j \\ FWT_{a_i} \cdot FWT_{b_i} = \sum_{j, j \& i = i} a_j \cdot \sum_{k, k \& i = i} b_j = \sum_{j, k, (j \& k) \& i = i} (a_jb_k) = FWT_{c_i} \]

\(FWT_a\) 和 \(a\) 的变换同上。

inline void FWT_AND(int *A) {
    for (int len = 2; len <= (1 << n); len *= 2)
        for (int x = 0; x < (1 << n); x += len)
            for (int i = x; i < x + len / 2; ++ i)
                A[i] = (A[i] + A[i + len / 2]) % mod;
}

inline void IFWT_AND(int *A) {
    for (int len = (1 << n); len >= 2; len /= 2)
        for (int x = 0; x < (1 << n); x += len)
            for (int i = x; i < x + len / 2; ++ i)
                A[i] = (A[i] - A[i + len / 2]) % mod;
}

\(\operatorname{xor}\)

这个比较难。

以下摘自 oi-wiki。

若我们令 \(x\circ y\) 表示 \(x\cap y\) 中 1 数量的奇偶性,即 \(x\circ y=\text{popcnt}(x\cap y)\bmod 2\),那么容易有 \((x\circ y)\operatorname{xor} (x\circ z)=x\circ(y\operatorname{xor} z)\)。

下证上式(\((x\circ y)\operatorname{xor} (x\circ z)=x\circ(y\operatorname{xor} z)\)):

只考虑 \(x\) 的二进制中为 1 的位,\(x\cap y\) 中 1 的数量 和 \(x\cap z\) 中 1 的数量可以分成三个部分:

1、都有的数量 \(A\)

2、仅有 \(y\) 有的数量 \(B\)

3、仅有 \(z\) 有的数量 \(C\)

即证明:\(((A + B) \bmod 2) \operatorname {xor} ((A + C) \bmod 2)= (B + C) \bmod 2\)

显然,当 \(A = B = C = 0\) 时上式成立,\(A\),\(B\),\(C\) 增加 1 并不会改变上述等式。

\(FWT[A]_i=\sum_{i\circ j=0}A_j-\sum_{i\circ j=1}A_j\),证明如下:

\[\begin{aligned} FWT[A]_iFWT[B]_i&=\left(\sum_{i\circ j=0}A_j-\sum_{i\circ j=1}A_j\right)\left(\sum_{i\circ k=0}B_k-\sum_{i\circ k=1}B_k\right) \\ &=\left(\sum_{i\circ j=0}A_j\sum_{i\circ k=0}B_k+\sum_{i\circ j=1}A_j\sum_{i\circ k=1}B_k\right)-\left(\sum_{i\circ j=0}A_j\sum_{i\circ k=1}B_k+\sum_{i\circ j=1}A_j\sum_{i\circ k=0}B_k\right) \\ &=\sum_{(j\oplus k)\circ i=0}A_jB_k-\sum_{(j\oplus k)\circ i=1}A_jB_k \\ &=FWT[C]_i \end{aligned} \]

inline void FWT_XOR(int *A) {
    for (int len = 2; len <= (1 << n); len *= 2)
        for (int x = 0; x < (1 << n); x += len)
            for (int i = x; i < x + len / 2; ++ i) {
                A[i] = (A[i] + A[i + len / 2]) % mod;
                A[i + len / 2] = (A[i] - 2 * A[i + len / 2]) % mod;
            }
}

inline void IFWT_XOR(int *A) {
    for (int len = (1 << n); len >= 2; len /= 2)
        for (int x = 0; x < (1 << n); x += len)
            for (int i = x; i < x + len / 2; ++ i) {
                A[i + len / 2] = 1ll * (A[i] - A[i + len / 2]) 
                                     * quick_pow(2, mod - 2) % mod;
                A[i] = (A[i] - A[i + len / 2]) % mod;
            }
}

同或

若我们令 \(x\circ y\) 表示 \(x\cup y\) 中 1 数量的奇偶性,即 \(x\circ y=\text{popcnt}(x\cup y)\bmod 2\)。

\(FWT[A]_i=\sum_{i\circ j=0}A_j-\sum_{i\circ j=1}A_j\)。

标签:circ,变换,sum,len,int,沃尔什,FWT,operatorname
From: https://www.cnblogs.com/chzhc-/p/18530960

相关文章

  • 基于Open-CV的多四边形检测方案(一):图像预处理与霍夫变换
    目录一、设计目标二、工作流程三、图像预处理与霍夫变换一、设计目标对于一个含有多个相邻四边形的图片,可以定位出其中每一个四边形的顶点。典型的案例如一个围棋棋盘,可以定位出所有的格子的点。软件工具:Python==3.9opencv-python==4.10.0.84numpy==1.22.4二......
  • (3)---【C语言】【GL库】【计算机图形学】DEV C++ 平台openGL库 下的画线图案设计 房
    声明:        由于本人是一名学生,现阶段还要完成学业,所以我们每周假期再回!谢谢大家理解和支持!上篇上手实践  运行结果 实现代码#include<windows.h>#defineGLUT_DISABLE_ATEXIT_HACK//处理不同系统的配置问题的宏#include<GL/glut.h>#include<std......
  • DEV C++ 平台【openGL】库 几何变换下图案设计 星状图形 与 圆 的画法实现 【C语言】
     项目实现话不多说,上干货!    在本文中,我们将探讨如何使用OpenGL库在DEVC++平台上绘制一个包含星状图形和圆的设计。功能简单介绍    该代码通过定义多个函数,实现了圆和星状图形的精确绘制。首先,DrawingCircle函数负责绘制圆,通过指定圆心坐标和半径,利用三角......
  • 号码变换配置对接运营商IMS
     概述freeswitch是一款简单好用的VOIP开源软交换平台。fs直接对接运营商,调试过程中的号码变换规则比较容易出问题。本文档记录一个较为通用的对接IMS配置方案。环境CentOS7.9freeswitch1.10.7模块配置号码变换主要使用mod_translate模块和dialplan拨号计划实现。确......
  • 【机器人学导论】简明学习笔记2.1——空间描述和变换(1/2)
    主要参考学习资料:《机器人学导论(第4版)》JohnJ.Craig著台大机器人学之运动学——林沛群(本文插图来自该课程课件)本章前置知识:矢量和矩阵的四则运算-单位矩阵-转置矩阵-逆矩阵-正交矩阵码字不易,求点赞收藏(´•ω•̥`)有问题欢迎评论区讨论~目录空间描述和变换描......
  • 项目实战:Qt+OpenCV仿射变换工具v1.1.0(支持打开图片、输出棋盘角点、调整偏移点、导出
    需求  1.打开图片;  2.矫正识别角点;  3.opencv摄像头操作子线程处理;  4.支持设置棋盘格的行列角点数; 背景  深入研究图像拼接细分支算法,产出的效果查看工具,验证算法单步思路。 相关博客  《项目实战:Qt+Opencv相机标定工具v1.3.0(支持打开摄像头、视......
  • 力扣题目解析--Z字形变换
    题目将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z字形排列。比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:PAHNAPLSIIGYIR之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYI......
  • Xor-FWT 的另一种理解方式
    Xor-FWT的另一种理解方式学习\(\text{Fennec'sAlgorithm}\)的额外收获,顺手记录一下。假设我们要求两个长度为\(n\)的数组的异或卷积,为方便起见令\(n=2^m\),也就是类似下面的形式\[C_k=\sum\limits_{i\oplusj}A_i\timesB_j\]考虑构造\(\mathbb{Z}_2^n\)中的向......
  • 彻底弄清楚LLC谐振变换器的直流增益特性
    这个图展示了LLC谐振变换器的直流增益特性,直流增益(输出电压与输入电压之比)随开关频率变化的关系。图中将增益曲线分为三个区域(Region1、Region2和Region3),每个区域对应不同的电路工作特性。以下是对每个区域的详细解释及其工作原理,以及LLC谐振变换器设计的基本思路。1.......
  • 华为OD机试 E卷|字符串变换最小字符串
    华为OD机试E卷|字符串变换最小字符串0、关于本专栏&刷题交流群本文收录于专栏【2024华为OD机试真题】,专栏共有上千道OD机试真题,包含详细解答思路、与四种代码实现(Python、Java、C++、JavaScript)。点击文末链接加入【华为OD机试交流群】,和群友一起刷题备考。刷的越多,考试中遇到......