Solution -「CF 1025G」Company Acquisitions
\(\mathcal{Description}\)
Link.
\(n\) 个公司,每个公司可能独立或者附属于另一个公司。初始时,每个公司附属于 \(a_i\)(\(a_i=-1\) 表示该公司独立)。不存在两级及以上的附属关系。每次事件随机选取两个独立的公司,使其中一个公司所拥有的附属公司全部独立,并且该公司成为另一个公司的附属。求使仅存在一个独立公司的期望操作次数。对 \(10^9+7\) 取模。
\(n\le500\)。
\(\mathcal{Solution}\)
奇怪的解题姿势增加了!
记一个公司的势能函数 \(\phi(i)=2^{s_i}-1\),其中 \(s_i\) 为该公司拥有的结点个数。并记 \(\phi(S)\) 为局面 \(S\) 的势能函数,有:
\[\phi(S)=\sum_{i=1}^n\phi(i)
\]
那么,结束局面 \(T\) 的势能函数 \(\phi(T)=2^{n-1}-1\)。
考虑单次事件对势能的影响。对于局面 \(S\) 中一次作用在两个独立公司 \(u,v\) 上的事件,有:
\[\begin{align}
E(\Delta\phi)&=E(\phi(S'))-\phi(S)\\
&=\frac{1}2((2^{s_u}-1)+(2^{s_v}-1))-(2^{s_u-1}-1)-(2^{2_v-1}-1)\\
&=-1+2\\
&=1
\end{align}
\]
一次事件在期望意义下会让局面的势能 \(+1\)!所以期望事件个数就是势能的期望变化次数。即:
\[\phi(T)-\phi(S)
\]
其中 \(S\) 是初始局面,\(T\) 即上文结束局面。输出这个值就好啦!
复杂度 \(\mathcal O(n)\)。
\(\mathcal{Code}\)
#include <cstdio>
const int MAXN = 500, MOD = 1e9 + 7;
int n, d[MAXN + 5];
inline int qkpow ( int a, int b, const int p = MOD ) {
int ret = 1;
for ( ; b; a = 1ll * a * a % p, b >>= 1 ) ret = 1ll * ret * ( b & 1 ? a : 1 ) % p;
return ret;
}
int main () {
scanf ( "%d", &n );
int ans = ( MOD + qkpow ( 2, n - 1 ) - 1 ) % MOD;
for ( int i = 1, f; i <= n; ++ i ) {
scanf ( "%d", &f );
if ( ~ f ) d[i] = -1, ++ d[f];
}
for ( int i = 1; i <= n; ++ i ) {
if ( ~ d[i] ) {
ans = ( ans - qkpow ( 2, d[i] ) + 1 + MOD ) % MOD;
}
}
printf ( "%d\n", ans );
return 0;
}