是(FWT)的例题了。
这里我做的题也不多,教练说尽可能多的讲。
只能给你们讲所有我做过的了。
1.按位或
http://hzoj.com/contest/126/problem/13
题解直接发链:https://www.cnblogs.com/Lrefrain/p/11655078.html
2.随机游走
http://hzoj.com/contest/220/problem/5
题解直接发链:https://www.cnblogs.com/Lrefrain/p/11655078.html
3.遗失的答案
http://hzoj.com/contest/126/problem/12
这个题不是很容易。(如果你要学(skyh)直接分治也可以,这里只讲(FWT)的方法)
首先可以发现这个东西只有八九个质因子,而我们的(gcd)是质因子幂取(min),(lcm)是取(max)。
考虑暴搜出全部符合条件的数,也就是满足(gcd|x,x|lcm,x<n)的全部(x)。
这样的数不会很多,线筛一下发现很大的也就700多个。
考虑状压全部的质因子的两种状态,表示是否达到了(gcd)的(min),和(lcm)的(max)。
挨个(dp)每个数。
这样的话我们正反两次(dp)。
得到(sum)和(suf)两个数组。
而考虑我们的答案是怎么样的。
要求前缀和后缀两者乘起来得到的或集合和当前这个数或起来得到全集。
那么对每个前缀后缀做一次或卷积,但是发现这样没法(O(1))回答问题,我们要求的集合必须是这个数的补给的超集,也就是说再做一次(AND_FWT)即可。
这样复杂度是对的,不过会被卡常。
因为做了四次(FWT)。
考虑容斥。
其实问题转化为一些集合的或为全集的情况下,要求某个集合必须被选中的方案。
先去掉后一个条件。
不考虑某个集合是否被选中,求某个集合的子集出现的方案。
首先(FWT)出有几个数是当前集合的子集,设为(cnt_s)。
这样方案就是(2^{cnt_s})
现在再考虑如何强制某个集合被选中。
当前这个集合的超集的方案全部都变成(2^{cnt_s-1})就相当于强制当前这个选中了。
然后看这个集合中必然不会出现的数的个数,利用这个数的个数进行容斥即可。
这里如果利用二项式反演来理解的话,其实就是至多形式的反演。
那个系数是((-1)^{mx-s})其实相当于是((-1)^{n-i})
这个样只需要做一次(FWT)即可。
4.州区划分
http://hzoj.com/problem/1315
事实上是(FMT)的板子题。
设分成了(T)个部分,每个部分的集合为(S_i)
首先我们要求的是:
事实上可以直接(dp)。
但是(dp)之前首先要判断一下集合的合法性,就是判断是否是一个联通的欧拉回路。
然后剩下的怎么做?
设(su[s]=sumlimits_{iin S}w_i)
设(dp[s])为当前已经处理的集合为(S)的答案。
那么初始化:
(dp[0]=1)
要求的是(dp[mx])
枚举当前添加进来的集合是(S-T),得到转移方程。
这样直接转移枚举子集的复杂度是(3^n)的。
肯定吃不消。
我们考虑如何优化这个过程呢?
这个过程事实上是一个裸的子集并卷积。
直接(FMT)即可。
复杂度是(O(n^22^n))