高维前缀和
引入
给定\(num\)个三元组\((x,y,z)\)。每次询问满足\(x \leq qx\) ,\(y \leq qy\) ,\(z \leq qz\) 的三元组个数。
\(x,y,z \leq n\),\(n \leq 10\),\(q ,num\leq 10^6\)
求解
容易想到维护\(Pre(x,y,z)\) 表示\(x' \leq x\) , \(y' \leq y\) , \(z' \leq z\) 的三元组个数
思路1
利用容斥原理求解。
由于容斥涉及的情况数目达到\(2^m\),故求解\(m\)维前缀和时间复杂度\(O(2^mn^m)\),\(m\)较大时难以求解。
思路2
考虑1维1维地累加(而不是思路1中的多维共同累加再减去重复的)
具体地,初始令\(Pre(x,y,z)=A(x,y,z)\),运算分多步执行:
- \(Pre(x,y,z)=\sum_{z'=1}^zPre(x,y,z')\)
- \(Pre(x,y,z)=\sum_{y'=1}^{y}Pre(x,y',z)\)
- \(Pre(x,y,z)=\sum_{x'=1}^{x}Pre(x',y,z)\)
求解m维前缀和的时间复杂度为\(O(mn^m)\)
实际执行时,将m元组压成m位n进制数作为数组下标 求解
应用
题意
给定n个m位数,问从中取出1些数,使得&值为0的方案数。答案对\(10^9+7\)取模,\(n \leq 10^6,m\leq 20\)
题解
本质上1个数等价于1个集合。则原问题等价于取出若干个集合,使其交集为空的方案数。
总体思路自然是容斥原理
抽象成函数,记\(f(s)\)表示交集包含\(s\)的方案数,\(cnt(s)\)表示\(s\)中1的个数则
首先考虑\(f(s)\)的求解
由于\(s\)为交集,故本质上只需求出包含集合\(s\)的集合个数\(num(s),则\)\(f(s)=2^{num(s)}-1\)
\(num(s)\)为给出的\(n\)个集合中\(s\)的超集个数,等价于求解“高维后缀和”。
而高维后缀和的实现可以转化为高维前缀和的逆序循环+反向贡献
由此可在\(m2^m\)时间内求出所有\(f(s)\),然后在\(2^m\)时间内求解\(Ans\)
时间复杂度\(O(m2^m)\) 代码见此