[AGC053C] Random Card Game 题解
首先发现 \(2n\) 这个数不可能被取走,所以我们最优的策略是取空另一堆牌,假设 \(2n\) 在 \(B\) 中。
考虑我们的最优策略下要取多少次牌,令 \(p_i\) 表示 \(B_{p_i} > A_i\) 中最小的 \(p_i\),令 \(d = \max_{i=1}^np_i-i\),当然 \(d\) 不能小于 \(0\)。则有结论,最优方案下取空 \(A\) 的次数为 \(n+d\)。因为我们需要 \(p_i-i\) 次操作删掉 \(B\) 中在 \(i\) 到 \(p_i\) 之间的牌,那就可以构造出一种操作序列使得只用多操作 \(d\) 次可以完成。
因为设恰好不好做,所以设 \(P(d)\) 表示至多操作 \(n+d\) 次能结束的概率,恰好 \(n+d\) 次就是 \(P(d)-P(d-1)\)。且有 \(P(n-1)=1\)。
答案就表示为 \(E=\sum_{d=0}^{n-1}(P(d)-P(d-1))\times (n+d)\),这个式子可以化简,但是不化也能做,只要会算 \(P(d)\) 就行了。
考虑 \(P(d)\) 怎么算,操作次数小于等于 \(n+d\) 的概率,即 \(\forall i \in[1,n]\),\(\exists j\in [1,\min(j+d,n)]\),使得 \(B_j>A_i\) 的概率。设事件 \(D_i\) 表示对于 \(A_i\) 来说上述条件成立。则 \(P(d)=P(D_1D_2D_3\dots D_n)\)。
根据概率的乘法公式,\(P(D_1D_2\dots D_n) = \prod_{i=1}^{n}P(D_i|D_1D_2\dots D_{i-1})\),这可以用条件概率说明,即 \(D_i\) 在前面所有事件发生的条件下发生的概率。
考虑正难则反,计算 \(P(\overline D_i|D_1D_2\dots D_{i-1})\)。什么情况下前面都行就 \(A_i\) 不满足呢,就是 \(A_i\) 要大于 \(A_{1\dots i-1}\) 的所有数,且大于 \(B_{1\dots \min(i+d,n)}\) 的所有数,既然数是随机分配的,那 \(P(\overline D_i|D_1D_2\dots D_{i-1}) = \frac{1}{i+\min(i+d,n)}\),则 \(P(D_i|D_1D_2\dots D_{i-1}) = \frac{i+\min(i+d,n)-1}{i+\min(i+d,n)}\)。
那么连乘起来,我们把 \(\min\) 拆掉,变成 \(P(d)=2\times \prod_{i=1}^{n-d} \frac{2i+d-1}{2i+d} \times \prod_{i=n-d+1}^{n} \frac{n+i-1}{n+i}\),因为 \(A,B\) 可以互换,所以要乘个 \(2\)。
这个式子肯定是不能临时算的,考虑化简。$ \prod_{i=n-d+1}^{n} \frac{n+i-1}{n+i}$ 拆开,等于 \(\frac{2n-d}{2n-d+1} \times \frac{2n-d+1}{2n-d+2} \times \dots \times \frac{2n-1}{2n}\),约分后就是 \(\frac{2n-d}{2n}\)。
再看前一项,$ \prod_{i=1}^{n-d} \frac{2i+d-1}{2i+d} = \frac{d+1}{d+2} \times \frac{d+3}{d+4} \times \dots \times \frac{2n-d-1}{2n-d}$,发现这可以预处理双阶乘来算,则其等于 \(\frac{(2n-d-1)!!(d)!!}{(d-1)!!(2n-d)!!}\)。总式 \(P(d) = \frac{(2n-d-1)!!(d)!!}{(d-1)!!(2n-d)!!} \times \frac{2n-d}{n}\)。可以做到 \(O(n \log n)\)。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define _int __int128
#define ull unsigned long long
#define pii pair<int,int>
#define fst first
#define scd second
#define pq priority_queue
#define mkp make_pair
#define popcount(x) __builtin_popcount(x)
#define endl '\n'
int n,m;
const int N = 1e6+10,mod=1e9+7;
int ans=0;
int qpow(int a,int b){
int res=1;
while(b){
if(b&1)res=(res*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return res;
}
int fac[2*N],inv[2*N],invn;
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
fac[0]=1;fac[1]=1;inv[0]=inv[1]=1;
for(int i=2;i<=2*n;i++){
fac[i]=(fac[i-2]*i)%mod;
inv[i]=qpow(fac[i],mod-2);
}
invn=qpow(n,mod-2);
ans=0;
int lst=0;
for(int d=0;d<n;d++){
int x=2*n-d;
x=(x%mod*invn)%mod;
x=(x%mod*fac[2*n-d-1]%mod*fac[d]%mod)%mod;
x=(x%mod*inv[2*n-d]%mod)%mod;
if(d)x=(x%mod*inv[d-1]%mod)%mod;
ans=(ans+(x-lst+mod)%mod*(n+d)%mod)%mod;
lst=x;
}
cout<<ans;
return 0;
}

浙公网安备 33010602011771号