$\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)\),我们发现我们需要满足:
\]
我们在脑中想一下,诶,似乎单位根满足这个条件诶!
于是,我们可以构造矩阵:
\]
而它的逆矩阵就是:
\]
一些例题
随机推荐
- Ubuntu 16.04LTS下eclipse连接mysql
第一部分:打开eclipse,新建一个web工程,新建一个类db_test.java(jdbc连接mysql的原理自行百度) import java.sql.*; public class db_te ...
- 取消Ubuntu开机硬盘自检
修改/etc/fstab文件,最后一列全改为0,测试能正常启动,尚未出现再次自检的情况 sudo gedit /etc/fstab
- RHEL7.2系统下的软件管理(yum)、本地yum源和网络yum源的搭建
在Liunx系统中,rpm和yum都可以安装软件,但rpm存在安装软件的依赖性,yum安装软件需要yum源 1.yum yum install softwarename ##安装 yum repoli ...
- Mybatis-Plus增强包
简介 本框架(Gitee地址 )结合公司日常业务场景,对Mybatis-Plus 做了进一步的拓展封装,即保留MP原功能,又添加更多有用便捷的功能.具体拓展体现在数据自动填充(类似JPA中的审计).关 ...
- 灵魂画手:漫画图解 SSH
OpenSSL 本身是一个软件库,这个软件被广泛的应用在系统服务器当中,他的主要功能是在网络通信的过程中,保证数据的一致性以及数据传输过程中的安全性.软件本身是由C语言编写,这使得他具备了跨平台的特性 ...
- Python+mirai开发QQ机器人起步教程(2021.9.9测试有效)
参考:开发 mirai QQ机器人起步教程_叹之-CSDN博客_mirai python 本篇文章参考了以上博客,并对其中的失效内容和版本匹配问题进行了补充修改,实测能够成功运行.部分步骤的运行截图见 ...
- 稚晖君-最小linux服务器运行 nginx + netcore
华为天才少年, B站科技大神,稚晖君(自称野生钢铁侠),多少科技爱好者拜服在他的全方位技术栈 今天我们就去入手一个他的量产产品 号称最小linux电脑 的"夸克" 到手之后,我们马 ...
- Java-SpringBoot整合SpringCloud
SpringBoot整合SpringCloud 1. SpringCloud特点 SpringCloud专注于为典型的用例和扩展机制提供良好的开箱即用体验,以涵盖其他情况: 分布式/版本化配置 服务注 ...
- Centos6.5时间服务器NTP搭建
NTP时间服务器安装与配置 第1章 Server端的安装与配置 1.1 查看系统是否已经安装ntp服务组件 rpm -qa | grep "ntp" #<==查看是否已经安装 ...
- Azure 实践(4)- CI/CD .netcore项目Docker构建及部署
上篇已介绍了.netcore项目构建的相关步骤,本篇继续完善 1.什么是CI/CD CI/CD 中的"CI"始终指持续集成,它属于开发人员的自动化流程.成功的 CI 意味着应用代码 ...