本文的核心內容很簡單,就是圍繞求\(n\)個點的有標號\(dag\)個數展開的一系列討論。
看資料範圍顯然只要用\(o(n^2)\)的做法就可以了。
考慮\(dag\)中必然存在入度為\(0\)的點,且去掉這些入度為\(0\)的點之後得到的依然是\(dag\)。
於是,我們可以設\(f_i\)表示\(i\)個點的有標號\(dag\)數目,列舉乙個\(j\)表示至少存在\(j\)個入度為\(0\)的點。
顯然有此時的方案數為:
\[c_i^j\times 2^\times f_
\]即,列舉選出哪\(j\)個點,列舉入度為\(0\)的點和其他點之間的邊是否選擇,而其他點依然形成\(dag\)可以直接從已有狀態轉移。
看到至少,我們可以考慮容斥。
因此得到最終的轉移方程:
\[f_i=\sum_^i(-1)^\times c_i^j\times2^\times f_
\]進一步考慮上面得到的式子,發現\(2^\)這個東西很難處理。
這需要乙個據說算是套路的轉化:
\[j\times(i-j)=\frac2-\frac2-\frac2
\]也就是說,原式就相當於:
\[f_i=\sum_^i\frac\times\frac}\sqrt2^}\times (-1)^\times f_
\]即:
\[\frac}=\sum_^i\frac}}\times\frac}}
\]令\(f(x)=\sum_^n\frac}x^i,g(x)=\sum_^n\frac}}x^i\),便有:
\[f(x)=g(x)*f(x)+1
\]稍微轉化一下就能得到:
\[f(x)=\frac1
\]首先我們依然要求出\(f_i\)。
然後我們再設乙個\(g_i\),轉移時去列舉\(1\)號點所在弱連通塊大小,可得:
\[g_i=f_i-\sum_^c_^g_jf_
\]發現\(g_i=c_^g_if_\),恰好能和\(\sum\)這一項拼在一起,也就是:
\[f_i=\sum_^ic_^g_jf_
\]拆開組合數得到:
\[\frac=\sum_^\frac\times\frac}
\]令\(f(x)=\sum_^n\fracx^i,g(x)=\sum_^n\fracx^i,h(x)=\sum_^n\fracx^i\),便有:
\[f(x)=g(x)*h(x)
\]因此:
\[g(x)=f^(x)*h(x)
\]好吧,餘對於多項式這類問題終究還是不夠熟練,仍需加強練習,唔姆。
多項式簡單應用
求 displaystyle sum na i cdot b i 對於求 displaystyle sum na i cdot b i 把b陣列翻轉一下,等價於求 displaystyle sum na i cdot b 這不就是乙個卷積嘛,時間複雜度 theta nlog n 你可能會說時間複雜度...
C 鍊錶應用 多項式相加
include using namespace std class poly class add2poly add2poly add2poly void add2poly addpoly read second poly cout n nsecond polynomial n end null fo...
鍊錶應用 多項式加法 乘法
鍊錶學習 多項式應用 通過引入insertpoly函式來完成加法乘法操作 以及類似功能的creat 函式,使我的多項式按照指數下降的方式插入節點 而不需要在輸入時人為的控制 include using namespace std 多項式adt鍊錶實現的型別宣告 typedef struct node...