牛客練習賽64 D

2021-10-06 09:52:51 字數 2081 閱讀 6457

【容斥原理經典題】

第i

ii個物品不能放在a

ia_i

ai​箱子裡,求每個箱子有乙個物品的方案數

經典題目

之前做了一道題,需要crt

crtcr

t合併(此題)

也是要考慮到容斥,那題處理方式是利用dpdp

dp,因為有個類似上公升子串行的遞推關係,dp[

i]

dp[i]

dp[i

]表示第乙個不合法的情況,之後無論怎麼選都還是不合法。

此題類似,g(n

)g(n)

g(n)

表示有n

nn個不合法的方案數,f(n

)f(n)

f(n)

表示任意排列的方案數。

顯然如果有k

kk個不合法,方案數顯然為g(k

)=g(

k)∗f

(n−k

)g(k)=g(k)*f(n-k)

g(k)=g

(k)∗

f(n−

k),比賽的時候沒考慮到任意排列,如果不任意的話是不能夠這麼乘的,只有任意的時候才不會被影響。

不過顯然,這樣子處理的時候,可能會有多於k

kk個不合法,所以我們定義g(k

)g(k)

g(k)

為至少k

kk個不合法。

根據容斥原理,答案為∑i=

0n(−

1)ig

(i

)\sum\limits_^n (-1)^ig(i)

i=0∑n​

(−1)

ig(i

)(至少有i

ii個不合法的情況,顯然包含g(i

+1

)g(i+1)

g(i+1)

,符合容斥原理的要求)。

最後求g(k

)g(k)

g(k)

的時候,令g[i

][j]

g[i][j]

g[i][j

]表示考慮前i

ii個物品不合法,有j

jj個不合法;

則有:g[i

][j]

=g[i

−1][

j]+g

[i−1

][j−

1]∗b

[i

]g[i][j]=g[i-1][j]+g[i-1][j-1]*b[i]

g[i][j

]=g[

i−1]

[j]+

g[i−

1][j

−1]∗

b[i]

,b [i

]b[i]

b[i]

表示要使當前盒子不合法,有幾種方法(不能放在該盒子的有幾個)。

因為資料較大,需要滾動陣列,或者用類似揹包逆推的方法。

#include

#define for(i,a,b) for(int i=a;i<=b;i++)

#define inf 0x3f3f3f3f

typedef

long

long ll;

using

namespace std;

const

int maxn =

3e5+10;

const

int maxm =

1e6+10;

const

int mod =

998244353

;ll f[maxn]

,g[maxn]

;ll a[maxn]

,x;int

main()

} ll ans=0;

for(

int i=

0,j=

1;i<=n;i++

,j*=-1

)ans=

(ans+

1ll*j*g[i]

*f[n-i]

)%mod;

cout<<

(ans+mod)

%mod<}

牛客練習賽64 D寶石裝箱

n 顆寶石裝進 n 個箱子使得 每個箱子中都有一顆寶石 其中第 i 顆寶石不能裝入第 ai 個箱子 求合法的裝箱方案數。總的裝箱方案為 n 答案 總方案數 sum f left i right 其中 f x 表示 x 個箱子不合法的方案數 我們定義 dp i j 表示前 i 個箱子有 j 個放了不合...

牛客練習賽64 題解

a 怪盜 1412題目描述 乙個長度為n m k包含n個數字1,m個數字2和k個數字4的陣列,最多可能有多少個子序列1412?如果乙個序列是陣列的子串行,當且僅當這個序列可以由陣列刪去任意個元素,再將陣列中的剩餘元素按順序排列而成。思路 將序列排列成111444441111222222,這樣可以得到...

牛客練習賽24 D

名字挺有意思的,排插樹,雖然這是個圖。算dijkstra的模版題,求最短路裡面最長的那條,因為到講台的距離總是取決於最短的那條路,但是又要求離講台最遠,那麼我們通過dijkstra計算出起始點到所有點的最短路然後遍歷找最大值就好。如下 include using namespace std type...