Educational Codeforces Round 98 (Rated for Div. 2) D
阿新 • • 發佈:2020-11-20
Educational Codeforces Round 98 (Rated for Div. 2) D
大意
有 \(n+2\) 個村莊,按從 \(0\) 到 \(n+1\) 標號。
村莊 \(1\) 到 \(n\) 中允許安裝燈塔,每個村莊有二分之一的概率被安裝(互相獨立)。
現在,對於一種安裝方法,你需要給予每個燈塔能量 \(p\in N^{*}\) 。
如果一個位於 \(i\) 的燈塔被賦予了能量 \(p\) ,那麼,所有滿足 \(|c-i|<p\) 的標號為 \(c\) 的村莊將會被照亮。
一種給予能量的方法合法,當且僅當滿足以下兩個條件:
1,\(0\) 和 \(n+1\) 不會被照亮。
2,其餘每個村莊都被照亮且僅被照亮一次。
問:
合法方案的概率是多少。
記答案為 \(\dfrac{x}{w}\)
思路
方案數,不是組合就是dp。
原題可以等價轉化為以下表述:
選擇任意段長度為奇數的區間恰好總長為n
考慮 \(dp[i]\) 表示區間長度為 \(i\) 時的方案數
得到
\(dp[2n+1]=dp[2n]+dp[2n-2]+...+dp[0]\)
\(dp[2n+2]=dp[2n+1]+dp[2n-1]+...+dp[1]\)
奇數項方案數為前面所有偶數項之和
偶數項方案數為前面所有奇數項之和
每種方案概率相等
總情況數 \(2^n\)
求逆元計算即可
程式碼
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; #define ll long long #define ull unsigned long long #define cint const int& #define Pi acos(-1) const int mod = 998244353; const int inf_int = 0x7fffffff; const ll inf_ll = 0x7fffffffffffffff; const double ept = 1e-9; int n; ll to[200200]; ll dp[200200]; ll ksm(ll bs, int x) { ll ans=1; while(x) { if(x&1) ans = (ans*bs) % mod; bs = (bs*bs) % mod; x >>= 1; } return ans; } int main() { to[0] = 1; cin >> n; for(int i=1; i<=n; i++) to[i] = (to[i-1]*2) % mod; dp[0]=1, dp[1]=1, dp[2]=1; ll odd=1, eve=2; for(int i=3; i<=n; i++) { if(i&1) { dp[i] = eve; odd = (eve+odd) % mod; } else { dp[i] = odd; eve = (eve+odd) % mod; } } cout << (dp[n]*ksm(to[n], mod-2)) % mod; return 0; }