$\text {FWT}$学习笔记
\(\text {FWT}\) 学习笔记
正常项的\(\text {FWT}\)
在\(\text {OI}\)中,我们经常会碰到这种问题:
- 给出一个长度为\(n\)的序列\(a_{1,2,...,n},b_{1,2,...,n}\),求出
\]
其中\(\oplus\)是定义的一种二进制下的运算。
对于这种问题,我们有一种通用的方法,我们称之为\(\text {FWT}\)。
我们考虑对于一个\(A\)构造一个\(FWT\)变换序列,满足:
\]
其中\(\times\)就是上文定义的卷积,\(\star\)是按位乘法。
我们考虑定义一种二进制运算的函数\(c(i,j)\),满足:
\]
于是,我们可以得到:
若存在:
\]
则有:
\]
\]
而我们根据\(FWT\)的定义我们又可以得到:
\]
\]
于是,我们就可以得到:
\]
不过因为是在二进制下的运算,所以一般构造的话都会满足
若
\]
则满足:
\]
于是,我们只需要知道\(c(0/1,0/1)\)即可。
但是,我们现在仅仅可以在\(\Theta(n^2)\)的时间复杂度内求出和转换\(FWT[A]\),显然不能满足我们的对优秀的时间的渴求。
我们想一下在\(\text {FFT}\)中,我们是如何做到\(\Theta(n\log n)\)转换的?分治!!!我们在\(\text {FWT}\)中也可以用类似的方法。
我们考虑对于当前的\(FWT[A]_i\)应该如何求出。
可以得到:
\]
\]
\]
其中\(FWT[A_0/A_1]\)就是子集的一个变换,与\(\text {FFT}\)类似。
我们发现如果我们构造转移矩阵:
\]
其实\(A\to FWT[A]\)每一次变换就是乘上\(\text {mat}\),那么\(FWT[A]\to A\)就是乘上\(\text {mat}\)的逆矩阵。逆矩阵直接手动构造即可。
一些例子
\(\wedge\)
对于并卷积,我们可以构造\(c(i,j)=[i|j]\),其中\([i|j]\)表示的是二进制下的\(i\)是二进制下的\(j\)的子集(每一位\(0/1\)相当于该元素是否在当前集合出现)。
\(\vee\)
对于或卷积,我们可以构造\(c(i,j)=[j|i]\)。
\(\oplus\)
对于异或卷积,我们可以构造\(c(i,j)=(-1)^{|i\wedge j|}\)。
模板题
就是上面三种运算的总和,代码戳这里打开。
非模板的一些例子
\(\text {FST}\)
我们需要解决这样一个问题:
- 给出一个长度为\(n\)的序列\(a_{1,2,...,n},b_{1,2,...,n}\),求出:
\]
对于这个问题,如果没有\(j\wedge k=0\)的话,这就是一个板的\(\text {FWT}\) \(\vee\)运算。我们发现其实\(j\wedge k=0\)的条件就相当于\(|j|+|k|=|j\vee k|\),于是,我们可以设二维数组\(f_i\),我们可以设转移式:
\]
其中\(h_{i,j}=[|j|=i]a_j,w_{i,j}=[|j|=i]b_j\)。
很显然,最后的\(c_i=f_{|i|,i}\)。
于是,我们就可以在\(\Theta(n\log^ 2 n)\)的时间复杂度内解决这个问题。
\(k\)进制下的\(\text {FWT}\)
我们发现上面的这个东西其实都是在\(2\)进制下面计算的,那么如果我们要拓展到\(k\)进制我们应该怎么办呢?
很显然,我们应该定义广义的\(\wedge,\vee,\oplus\)。
- $\wedge $
在\(k\)进制下,定义\(a\wedge b=\min\{a,b\}\)
- \(\vee\)
在\(k\)进制下,定义\(a\vee b=\max\{a,b\}\)
- \(\oplus\)
在\(k\)进制下,定义\(a\oplus b=(a+b)\bmod k\)
因为\(\wedge,\vee\)不是很常用,所以这里着重介绍一下\(\oplus\)。
我们要考虑如何构造\(c(i,j)\),我们发现我们需要满足:
\]
我们在脑中想一下,诶,似乎单位根满足这个条件诶!
于是,我们可以构造矩阵:
\]
而它的逆矩阵就是:
\]
一些例题
随机推荐
- vmware 配置不同网段双网卡。
一.前言 需求:由于LVS演练需要,需要配置两张linux OS网卡,而且是不同网段. 准备: 物理机:单网卡 VMware:centos 6.8 二.配置 第一步:新建虚拟机VMware,cento ...
- Vue.JS快速上手(指令和实例方法)
1.声明式渲染 首先,我们要知道Vue是声明式渲染,那啥是声明式渲染,我们只需要告诉程序我们想要什么结果,其他的交给程序来做.与声明式渲染相对的是命令式渲染,即命令我们的程序去做什么,程序就会跟着你的 ...
- Kubernetes集群部署笔记
本作品由Galen Suen采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可.由原作者转载自个人站点. 概述 本文用于整理基于Debian操作系统使用kubeadm工具部署Kub ...
- MySQL主库手动复制至从库
原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 主库手动复制至从库 1.1 Master主库锁表 1.2 主库备份 1.3 从 ...
- .NET 5 支持 Azure Functions OpenAPI 扩展啦
今年5月,在 Build大会上,Azure FunctionsOpenAPI的功能支持(预览版)正式宣布. 当时,它最高支持 v3 运行时--.NET Core 3.1 版本. 最近,它发布了 .NE ...
- C# Dapper基本三层架构使用 (三、DAL)
数据访问层(DAL),主要是存放对数据类的访问,即对数据库的添加.删除.修改.更新等基本操作 首先需要在UI层App.Config配置文件中增加连接字符串,如下所示 <connectionStr ...
- Activiti 学习(三)—— Activiti 流程启动并完成
Activiti 流程启动 流程定义部署后,就可以通过工作流管理业务流程了,也就是说前文部署的出差申请流程可以使用了.针对该流程,启动一个流程表示发起一个新的出差申请单,这就相当于 java 类与 j ...
- mysql中varchar类型和datetime类型字段进行比较
我是在mysql5.7版本进行比较 表a的字段order_no和表iwebshop_tmp的字段order_no一样 需要更新iwebshop_member_order表的datetime类型expi ...
- Jmeter系类(32) - JSR223(2) | Groovy常见内置函数及调用
常见内置函数及调用 获取相关函数 获取返回数据并转换为String字符串 prev.getResponseDataAsString() 例子 String Responsedata = prev.ge ...
- jmeter监控linux服务器资源
https://blog.csdn.net/weixin_38102592/article/details/100136375 https://blog.csdn.net/liuqiuxiu/arti ...