HNOI 2011 卡農 題解

2021-10-09 21:17:12 字數 1277 閱讀 1645

題目傳送門

題目大意:有乙個集合

\,你要選出他的若干個子集組成長度為 n

nn 的序列,滿足:不存在相同的子集;不能有空集;每種元素在所有子集**現次數總數為偶數。問有多少個不同的序列——兩個序列相同當且僅當 a

aa 可以重新排列得到 bbb。

由於序列中每個子集不同,所以可以先不考慮序列相同的問題,最後使答案除以 m!m!

m!即可。

設 f [k

]f[k]

f[k]

表示長度為 k

kk 的滿足三個要求的序列數量,轉移時考慮用總方案數減去不合法方案數:

總方案數:考慮只滿足限制 3

33 的序列數,發現當確定了前 k−1

k-1k−

1 個集合後,第 k

kk 個集合是唯一的,所以方案數為 a2n

−1k−

1a_^

a2n−1k

−1​。

不滿足限制 1

11 的:如果有乙個子集和第 k

kk 個 子集相同,那麼去掉這兩個子集後序列依然合法,方案數為 f[k

−2

]f[k-2]

f[k−2]

,再考慮這個相同子集的位置,有 k−1

k-1k−

1 個位置可選,最後考慮這個子集是什麼,有 2n−

k+

22^n-k+2

2n−k+2

種選擇,方案數為 f[k

−2]×

(k−1

)×(2

n−k+

2)

f[k-2]\times(k-1)\times(2^n-k+2)

f[k−2]

×(k−

1)×(

2n−k

+2)不滿足限制 2

22 的:去掉這個空集依然合法,方案數為 f[k

−1

]f[k-1]

f[k−1]

。 於是就可以 o(m

)o(m)

o(m)

遞推了,**如下:

#include

#define maxn 1000010

#define mod 100000007

int n,m;

int a[maxn]

,f[maxn]

;int

ksm(

int x,

int y)

intmain()

HNOI2011 卡農 題解

真 狀壓dp 啥比題面 等價於在 s 中選 m 個數 無序 滿足 問方案數,對 10 8 7 取模 這個無序是個假的,最後除掉 m 就完了,設 dp 表示選了 k 個數的方案數 考慮容斥,顯然如果前 k 1 個數都確定了,則第 k 個數也就確定了 第 k 個數為前面數的異或和 於是直接大力選,方案數...

HNOI2011 數學作業

hnoi2011 數學作業 小 c 數學成績優異,於是老師給小 c 留了一道非常難的數學作業題 給定正整數 n 和 m 要求計算concatenate 1.n mod m 的值,其中 concatenate 1.n 是將所有正整數 1,2,n順序連線起來得到的數。例如,n 13,concatenat...

HNOI2011 數學作業

我又對著跑出正解的程式調了好久 怕不是眼瞎了 這就是個分段矩陣,我們很容易就得到了遞推式 f i f i 1 10 k i 其中 k log i 於是就是分段矩陣 矩陣 之後就是 了,沒有加快速乘wa了好久 cpp include include include define re register...