FMT 和 子集卷积

FMT 和 子集卷积

FMT

给定数列 $ a_{0\dots 2^{k}-1} $ 求 $ b $ 满足 $ b_{s} = \sum_{i\in s} a_i $

实现方法很简单,

for( i in 0..n-1 )
    for( j in 0..2^n-1)
        if( j & ( 1 << i ) )
            a[j] += a[j ^ ( 1 << i )]

然后称为 $ B = FMT(A) $ ,快速莫比乌斯变换

想要还原也很简单,把代码反着写:

for( i in n-1 downTo 0 )
    for( j in 2^n - 1 downTo 0)
        if( j & ( 1 << i ) )
            a[j] -= a[j ^ ( 1 << i )]

当然, $ i $ 的顺序可以是原来的顺序,因为按照哪个顺序枚举位根本不重要

同时,$ j $ 的顺序也不重要,考虑对于一个数字,它只有在当前枚举的位数为 1 的时候才被执行,所以就算已经枚举到这位是 0 的状态,它也不会被更新。

这样 $ A = IFMT( B ) $

FMT 可以写成 FFT 那样的形式,就不赘述了。

或卷积

或卷积就需要用到这个东西。

或卷积是指:
\[
C_x = \sum_{i|j=x} A_i B_j
\]
有一个结论, $ FMT(C) = FMT(A) + FMT(B) $

原因是 $ (i | j) = s $ 等价于 $ (i \sube s) and (j \sube s) $

所以有 $ C = IFMT( FMT(A) + FMT(B) ) $

于是可以 $ O(n2^n) $ 做这个。

子集卷积

子集卷积张这样:
\[
C_s = \sum_{i|j=s,i\&j = 0} A_i B_j
\]

如果设 $ p(x) $ 为 $ x $ 的 popcount ,那么:
\[
(i|j = s) , (i\&j = 0) \Leftrightarrow i|j = s , p(i)+p(j) = p(s)\\C_s = \sum_{i|j = s , p(i)+p(j) = p(s)} A_iB_j
\]
我们把 $ c $ 扩展到二维,设 $ c‘{p,k} $,定义如下:
\[
c'_{p,s} = \sum_{i|j = s,p(i)+p(j) = p} a_ib_j[p(s) = p]
\]
把 $ c $ 扩展到二维了,$ a $ 也需要扩展到二维,所以定义 $ a‘
{p,s} $
\[
a'_{p,s} = \left\{\begin{aligned}&0 & {p(s) \neq p}\\&a_{s} & {p(s) = p} \end{aligned}\right.
\]
同理定义 $ b‘_{p,s} $

我们知道
\[
c'_{p,s} = \sum_{i|j = s,p(i)+p(j) = p} a'_{p(i),i} b'_{p(j),j}
\]
观察到 $ c‘p = \sum{i=0}^p a‘{i}\times{or} b‘_{p-i} $ ,而且需要去掉左边的 $ p(s) \neq p $ 的情况。

这样复杂度 $ O(n^3 2^n) $,一共要卷 $ n^2 $ 次。

注意 $ FMT , IFMT $ 都有可加性,所以我们把那个或卷积写成 $ FMT $ 的形式
\[
\begin{aligned}c'_{p} &= \sum_i IFMT(FMT(a'_i) · FMT(b'_{p-i}))\\&= IFMT( \sum_i FMT(a_i') · FMT(b_{p-i}') )\end{aligned}
\]
我们现在只需要处理出所有 $ a‘_i $ 和 $ b‘_i $ 的卷积,最后再跑 $ n $ 次逆 FMT ,所以这样做就优化到了 $ O( 2^n n^2 ) $

原文地址:https://www.cnblogs.com/yijan/p/12387352.html

时间: 2024-11-10 19:11:45

FMT 和 子集卷积的相关文章

CF 914 G Sum the Fibonacci —— 子集卷积,FWT

题目:http://codeforces.com/contest/914/problem/G 其实就是把各种都用子集卷积和FWT卷起来算即可: 注意乘 Fibonacci 数组的位置: 子集卷积时不能一边做一边更新卷积的数组! 代码如下: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int rd() { int ret=

Future Failure CodeForces - 838C (博弈论,子集卷积)

大意: 两人轮流操作一个长$n$, 只含前$k$种小写字母的串, 每次操作删除一个字符或者将整个串重排, 每次操作后得到的串不能和之前出现过的串相同, 求多少种串能使先手必胜. 找下规律发现$n$为奇数必胜, 否则假设$a_i$为字符$i$出现次数, 如果$\frac{n!}{a_1!a_2!...a_k!}$为奇数则必败 $n!$中$2$的幂次为n-__builtin_popcount(n) 所以必败就等价于$a_1+...+a_n=a_1|...|a_n$ 设$f_{i,j}$表示前$i$个

hdu 6057 Kanade&#39;s convolution(子集卷积)

题解: 然后就是接下来如何fwt 也就是如何处理bit(x) - bit(y) = bit(k)这个条件. 其实就是子集卷积. 把bit(x)和bit(y)划分成两个集合,然后就是子集卷积的形式. 这里设两个新的数组 A[bit(y)][y], B[bit(x)][x],代表拆出来的相应数组 然后对这两个数组做fwt,得到其点值表示,然后直接在外层枚举x和y的大小然后做卷积即可. 这样说可能很抽象,其实贴出代码就很清楚了 #include <iostream> #include <vec

CF914G Sum the Fibonacci FWT、子集卷积

传送门 一道良心的练习FWT和子集卷积的板子-- 具体来说就是先把所有满足\(s_a \& s_b = 0\)的\(s_a \mid s_b\)的值用子集卷积算出来,将所有\(s_a \oplus s_b\)用xor卷积算出来,把斐波那契数代进去,然后将三个数组and卷积,最后取\(2^i (i \in Z)\)的位置的答案的和 #include<bits/stdc++.h> //this code is written by Itst using namespace std; int

集合并卷积的三种求法

也许更好的阅读体验 本文主要内容是对武汉市第二中学吕凯风同学的论文<集合幂级数的性质与应用及其快速算法>的理解 定义 集合幂级数 为了更方便的研究集合的卷积,引入集合幂级数的概念 集合幂级数也是形式幂级数的一种,只是集合的一种表现形式,无需考虑收敛或发散的含义 定义一个集合 \(S\) 的集合幂级数为 \(f\) ,那么我们就可以把集合 \(S\) 表示为如下形式 \(\begin{aligned}f=\sum _{T\subseteq S}f_{T}\cdot x^{T}\end{align

bzoj5153 [Wc2018]州区划分

题目链接 正解:子集和变换. 考场上只会暴力和$p=0$的情况,还只会$O(2^{n}*n^{3})$的. 然而这题题面出锅,导致考场上一直在卡裸暴力,后面的部分分没写了..听$laofu$说$O(2^{n}*n^{3})$可以过.. 所以直接讲正解.. 我们假设每个城市可以在两个不同集合,那么可以把子集卷积变成或卷积. 我们只要记下当前总共有多少个点,于是考虑设$f[i][S]$表示$i$个点,集合为$S$的方案数. 最后的$f[n][all]$就是答案,显然这个状态中的每个城市只会出现一次.

UOJ#348. 【WC2018】州区划分

原文链接www.cnblogs.com/zhouzhendong/p/UOJ348.html 前言 第一次知道子集卷积可以自己卷自己. 题解 这是一道子集卷积模板题. 设 $sum[S]$ 表示点集 S 的点权和. 设 $f[S]$ 表示对点集 S 进行州区划分得到的答案,定义 $g[S]$ 在点集 S 合法时为 $(sum[S])^p$,不合法时为 0 . 则 $$f[S] = \frac{1}{(sum[S])^p}\sum_{T\subsetneq S} f[T]g[S-T]$$ 这东西是

WC2018 滚粗记

虽然又考炸了但还是总结一下.. $day0$:没有什么很重要的事.. $day1$:除了听(dong)课(mian)以外没有什么很重要的事.. $day2$:除了听(dong)课(mian)以外没有什么很重要的事.. $day3$:除了听(dong)课(mian)以外没有什么很重要的事.. $day4$:除了听(dong)课(mian)以外没有什么很重要的事.. 所以重点总结一下考试咯.. $day5$: 开考了,马上看了一下题目.. 不对啊,$t1$怎么这么送啊,直接送了$68$分啊.前面的暴

# 清北冬令营真题泛做

清北冬令营真题泛做 前言 这段时间为了准备冬令营把清北冬令营真题都做了一下.更个博回顾一下(免得你们老说我咕咕咕). 先写良心PKU的题再写THU的题, 主要是THU的题和PKU比起来真的毒瘤好多...... PKUWC2018 [PKUWC2018]Minimax 一个比较显然的暴力是归并排序,每次直接前后缀计算答案即可. 为啥不用线段树合并代替归并排序呢? 暴力线段树合并,合并的过程中顺便算一下即可,由于权值区间不交所以复杂度一个\(log\). [PKUWC2018]Slay the Sp