給定\(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\)較大時難以求解。
\[pre(x,y,z)=a(x,y,z)+pre(x-1,y,z)+pre(x,y-1,z)+pre(x,y,z-1)-pre(x-1,y-1,z)-pre(x-1,y,z-1)-pre(x,y-1,z-1)+pre(x-1,y-1,z-1)
\]思路2
考慮1維1維地累加(而不是思路1中的多維共同累加再減去重複的)
具體地,初始令\(pre(x,y,z)=a(x,y,z)\),運算分多步執行:
\(pre(x,y,z)=\sum_^zpre(x,y,z')\)
\(pre(x,y,z)=\sum_^pre(x,y',z)\)
\(pre(x,y,z)=\sum_^pre(x',y,z)\)
求解m維字首和的時間複雜度為\(o(mn^m)\)
實際執行時,將m元組壓成m位n進製數作為陣列下標 求解
codeforces 449d
題意給定n個m位數,問從中取出1些數,使得&值為0的方案數。答案對\(10^9+7\)取模,\(n \leq 10^6,m\leq 20\)
題解本質上1個數等價於1個集合。則原問題等價於取出若干個集合,使其交集為空的方案數。
總體思路自然是容斥原理
抽象成函式,記\(f(s)\)表示交集包含\(s\)的方案數,\(cnt(s)\)表示\(s\)中1的個數則
\[ans=\sum_^f(s)(-1)^
\]首先考慮\(f(s)\)的求解
由於\(s\)為交集,故本質上只需求出包含集合\(s\)的集合個數\(num(s),則\)
\(f(s)=2^-1\)
\(num(s)\)為給出的\(n\)個集合中\(s\)的超集個數,等價於求解「高維字尾和」。
而高維字尾和的實現可以轉化為高維字首和的逆序迴圈+反向貢獻
由此可在\(m2^m\)時間內求出所有\(f(s)\),然後在\(2^m\)時間內求解\(ans\)
時間複雜度\(o(m2^m)\)
**見此
學習筆記 高維字首和
求 sum i n i a i 實際上,這只是高維字首和的一種特殊形式,即每一維的大小都為 2.我們計算矩陣字首和時,通常用的是容斥的方法.設當前要計算 d 維字首和,容斥的複雜度為 sum n binom 2 d 當維數過大時顯然不行.我們考慮計算矩陣字首和的另一種方法 先算出每一列的字首和,然後...
hihocoder1496(高維字首和)
題意 給定n個數a1,a2,a3,an,小ho想從中找到兩個數ai和aj i j 使得乘積ai aj ai and aj 最大。其中and是按位與操作。第一行乙個整數n 1 n 100,000 第二行n個整數a1,a2,a3,an 0 ai 2 20 分析 嘗試列舉and值z,那麼問題就變成了找尋最...
sosdp(高維字首和)學習筆記
我們先看一維字首和 for int i 1 i n i s i s i 1 那麼二維字首和 for int i 1 i n i for int j 1 j n j s i j s i 1 j s i j 1 s i 1 j 1 這個是根據容斥計算的,維度很高的時候就不行了 我們換一種方法 for i...