BZOJ2339 卡農(遞推,容斥)

2021-08-21 04:01:04 字數 1648 閱讀 4254

bzoj

先簡化一下題意: 在[

1,2n

−1] [1,

2n−1

]中選擇不重複的

m m

個數,使得他們異或和為

0' role="presentation">0

0的方案數。

我們設f[i

] f[i

]表示選擇

i i

個數異或和為

0' role="presentation">0

0的方案數。

直接算是很麻煩的,所以我們反過來,總數減去不合法的。

因為確定了前i−

1 i−1

個數最後乙個數就已經知道了。

所以總方案數是ai

−12n

−1a 2n

−1i−

1,不合法的有兩種,一種是選擇了

0 0

,一種是有重複。

選擇了0

' role="presentation">0

0,意味著前i−

1 i−1

個數的異或和為

0 0

,所以方案數是f[

i−1]

' role="presentation">f[i

−1]f

[i−1

]種。

有重複,我們列舉哪個數重複了,那麼剩下的i−

2 i−2

個數的異或和仍然為

0 0

所以方案數是f[

i−2]

×(2n

−1−(

i−2)

)' role="presentation">f[i

−2]×

(2n−

1−(i

−2))

f[i−

2]×(

2n−1

−(i−

2)),題目沒有考慮順序,但是我們計算的時候先考慮了順序,所以這裡的方案數還需要考慮在哪個位置,也就是再乘上乙個(i

−1) (i−

1)

所以f[

i]=a

i−12

n−1−

f[i−

1]−(

i−1)

×f[i

−2]×

(2n−

1−(i

−2))

f [i

]=a2

n−1i

−1−f

[i−1

]−(i

−1)×

f[i−

2]×(

2n−1

−(i−

2)

)最終的答案再把順序的問題處理一下就好了。

#include

#include

using

namespace

std;

#define mod 100000007

#define max 1000100

inline

int read()

int jv=1,a[max],n,m,p,f[max];

int fpow(int a,int b)

return s;

}int main()

bzoj 3622 容斥原理

題意 給出有n個元素的集合a和集合b,所有2n個元素互不相同,求將a集合中的元素和b集合中的元素兩兩配對,使a的元素大於b中元素的對數恰為n k2對。設f i j 表示a中的前i個元素配對後至少有j對滿足a的元素大於b中元素。那麼先將a和b排序,設ne x i 表示b中最後乙個小於a中i元素的位置。...

BZOJ 1176 Mokia(CDQ分治 容斥)

description 維護乙個w w的矩陣,初始值均為s.每次操作可以增加某格仔的權值,或詢問某子矩陣的總權值.修改運算元m 160000,詢問數q 10000,w 2000000.input 第一行兩個整數,s,w 其中s為矩陣初始值 w為矩陣大小 接下來每行為一下三種輸入之一 不包含引號 1 ...

BZOJ 1042 硬幣購物 (數論 容斥)

time limit 10 sec memory limit 162 mb description 硬幣購物一共有4種硬幣。面值分別為c1,c2,c3,c4。某人去商店買東西,去了tot次。每次帶di枚ci硬幣,買s i的價值的東西。請問每次有多少種付款方法。input 第一行 c1,c2,c3,c...