原題:[清華集訓2012]串珠子
加強版:串珠子 加強版
這道題基本思路與之前寫過題解的轟炸方案一樣,可見這是一種常用的套路了。
大概翻了翻題解,發現大部分都是用的狀壓dp+列舉子集,時間複雜度 \(o(3^n)\)。
這裡提供乙個 \(o(n^2 2^n)\) 的做法,實測可以在 2s 內通過 \(n<=20\) 的資料,目前排全站第一。
前置知識:快速莫比烏斯變換、子集卷積
前面的推式子都差不多,但這裡還是說一下。
我們定義:
\(f_s\) 表示\(s\)集合構成連通圖的方案數;
\(g_s\) 表示\(s\)集合亂連的總方案(即不保證連通)。
我們通過遞推的方式求 \(g\) :
\[g_s=g_ \prod\limits_ (c_+1)
\]其中 \(s'\) 為 \(s\) 中去掉任意某元素 \(p\) 所得,「 \(+1\) 」即可以不連。
直接求連通方案 \(f\) 不好求,但我們考慮算不連通方案,再用總方案去減。
對於不連通方案,只要圖有兩個以上的連通塊,這個圖就不連通了。我們抓住這個特點,考慮列舉其中乙個連通塊,其他的點任其自生自滅,只要不連向我們列舉的連通塊,隨便連,這樣的圖肯定是不連通的。
但直接列舉可能算重,即我們現在列舉了乙個連通塊 \(t\),之後列舉另乙個連通塊 \(t'\) 時,\(t\) 出現在了自生自滅的那些點中,這顯然會重複計算。
只要我們先後列舉的連通塊總是有交,就一定不會算重了。考慮從 \(s\) 中抽出乙個點 \(p\),列舉的所有連通塊中均包含 \(p\),就不會出現上述情況。跟上個式子一樣,\(s'\) 為 \(s\) 中去掉任意某元素 \(p\) 所得:
\[f_s=g_s-\sum\limits_g_f_}
\]這裡圖方便用減號代替了補集符號,大家看的懂就行。
做到這一步,已經可以用 \(o(3^n)\) 列舉子集做了。下面我將對式子做一些變換,來做到更優複雜度。
看著這個式子,是不是挺像子集卷積?那我們就把它變得更子集卷積。
注意到原式子中 \(t\) 是不能取 \(s'\) 的,於是我們移項並合併:
\[\sum\limits _g_f_} =g_s
\]其實式子已經變完了(真·一點點變換),但為了求出答案,我們改變一下 \(p\) 的定義。
\(p\) 可以是 \(s\) 中的任意元素,於是我們欽定 \(p\) 為 \(s\) 中最高位元素,即 \(p=highbit(s)\)。
設總點數為 \(n\),考慮 \(s\) 取遍 \([2^,2^n-1]\),則 \(p=2^\),\(s'\in [0,2^-1]\) 。
回頭看我們的式子,發現其實就是 \(g\) 前半段與 \(f\) 後半段子集卷積後變成了 \(g\) 後半段。
這裡設 \(g_0\) 為 \(g\) 前半段,\(g_1\) 為後半段,\(f\) 同理:
\[g_0*f_1=g_1
\]\[f_1=\frac
\]其中 \(*\) 為子集卷積,除號即為其逆運算。
而 \(g\) 是已知的,且答案為 \(f_\) 在 \(f\) 後半段中,於是就在 \(o(n^2 2^n)\) 完成了此題。
順帶一提,子集卷積求逆直接分別對 \(g_0\) , \(g_1\) fmt,對位做多項式除法,最後 ifmt 即可。由於項數很少只有 \(n\),暴力除即可。
#include#define r register int
#define ll long long
#define i inline
using namespace std;
const int n=20,m=1<=p)a-=p;}
i void mns(int &a,int b)
struct poly
pc[0]=-1;//這裡圖方便把初值設為了-1,但其實後面會變成0
for(r i=0;ifmt(g0);fmt(g1);
for(r i=0;iifmt(g1);
printf("%d",g1[l-1].a[n]);
return 0;
}
洛谷P4228 清華集訓2017 榕樹之心
先只考慮根節點是否合法。發現兩個來自不同子樹的點可以消去,那麼只需判定所有點能否兩兩消去,使心停留在根節點即可。發現其可以轉化為乙個模型 有若干個集合,每個集合內有若干個點,每次可以消去兩個來自不同集合的點。設集合點數總和為 sum 最大集合點數為 max 得 sum max geqslant ma...
P2260 清華集訓2012 模積和
數學題,無背景。求 sum limits sum limits n bmod i times m bmod j i neq j bmod 19940417 的值 輸入格式 兩個整數n m 輸出格式 答案 mod 19940417 輸入樣例 1 3 4 輸出樣例 1 1 輸入樣例 2 123456 6...
(寒假集訓)洛谷 P2058 海港
小k是乙個海港的海關工作人員,每天都有許多船隻到達海港,船上通常有很多來自不同國家的乘客。小k對這些到達海港的船隻非常感興趣,他按照時間記錄下了到達海港的每一艘船隻情況 對於第i艘到達的船,他記錄了這艘船到達的時間ti 單位 秒 船上的乘 客數星ki,以及每名乘客的國籍 x i,1 x i,2 x ...