CF1025G Company Acquisitions 题解

Description

nn 个初创公司。每个公司可以是活跃的或已被收购的。如果一个公司被收购了,说明它正好跟随一个活跃的公司。一个活跃的公司可以被任意多个已被收购的公司跟随。活跃的公司不能跟随其他公司。

以下过程会一直进行,直到只剩下一个活跃的公司。每次执行下列步骤需要恰好 1 天:

  1. 随机等概率选出两个不同的活跃公司 AABB
  2. 掷一次公平的硬币,等概率地决定 AA 收购 BBBB 收购 AA(即如果 AA 收购 BB,那么 BB 的状态从活跃变为已被收购,并开始跟随 AA)。
  3. 当一个公司从活跃变为已被收购时,它之前所有已被收购的下属公司都会变为活跃状态。

例如,可能出现如下情形:假设 AABB 是活跃公司,CCDDEEAA 的已被收购公司,FFGGBB 的已被收购公司:


红色表示活跃公司。

如果 AA 收购 BB,则状态变为 AAFFGG 是活跃公司,CCDDEEBBAA 的已被收购公司,FFGG 没有下属:

如果反过来 BB 收购 AA,则状态变为 BBCCDDEE 是活跃公司,FFGGAABB 的已被收购公司,CCDDEE 没有下属:

现在给定初创公司的初始状态。对于每个公司,告知其是活跃还是已被收购。如果是已被收购,还会给出它当前跟随的活跃公司的编号。

你需要计算,最终只剩下一个活跃公司时,所需天数的期望值。

可以证明,期望天数可以表示为有理数 P/QP/Q,其中 PPQQ 是互质整数,且 Q0(mod109+7)Q \not= 0 \pmod{10^9+7}。请输出 PQ1P \cdot Q^{-1}109+710^9+7 的结果。

Solution

对于这类比较复杂的操作,问期望时间的问题有个技巧是用鞅与停时定理做。

具体地,设 f(x)f(x) 为一个固定函数,定义当前局面的权值是一个有关 f(x)f(x) 的确定组合,然后我们通过确定 ff 来让每次操作后局面的期望权值总减少恰好 11,期望时间也就能用初始期望减去结束期望来算。

这题我们设 aia_i 为第 ii 个菊花的大小,定义一个局面的权值为 f(ai)\sum f(a_i),那么一次操作后权值的期望变化量为

Δ=1m(m1)i=1mji[f(ai+1)+(aj1)f(1)f(ai)f(aj)]=1mi=1m[f(ai+1)+(ai1)f(1)2f(ai)]=1\begin{aligned} \Delta=&\frac{1}{m(m-1)}\sum_{i=1}^{m}{\sum_{j\neq i}}{\left[f(a_i+1)+(a_j-1)f(1)-f(a_i)-f(a_j)\right]}\\ =&\frac{1}{m}\sum_{i=1}^{m}{\left[f(a_i+1)+(a_i-1)f(1)-2f(a_i)\right]}=-1\\ \end{aligned}

由于我们可以随意确定 f(x)f(x) 的值,所以这里让 f(1)=0f(1)=0,并让 f(ai+1)2f(ai)f(a_i+1)-2f(a_i) 恒为 1-1 即可满足等式的条件。也就是说 f(x)=2f(x1)1f(x)=2f(x-1)-1,初始条件是 f(1)=0f(1)=0。容易得到 f(x)=12x1f(x)=1-2^{x-1}

最终答案为 f(ai)f(n)\sum f(a_i)-f(n),其中 aia_i 为初始状态下第 ii 个菊花的大小。

时间复杂度:O(n)O(n)

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <bits/stdc++.h>

// #define int int64_t

const int kMaxN = 505, kMod = 1e9 + 7;

int n;
int cnt[kMaxN];

int qpow(int bs, int64_t idx = kMod - 2) {
int ret = 1;
for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod)
if (idx & 1)
ret = (int64_t)ret * bs % kMod;
return ret;
}

inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); }
inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); }
inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; }
inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }

void dickdreamer() {
std::cin >> n;
for (int i = 1; i <= n; ++i) {
int x;
std::cin >> x;
if (x == -1) ++cnt[i];
else ++cnt[x];
}
int ans = 0;
for (int i = 1; i <= n; ++i)
if (cnt[i])
inc(ans, sub(1, qpow(2, cnt[i] - 1)));
dec(ans, sub(1, qpow(2, n - 1)));
std::cout << ans << '\n';
}

int32_t main() {
#ifdef ORZXKR
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) dickdreamer();
// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
return 0;
}

CF1025G Company Acquisitions 题解
https://sobaliuziao.github.io/2025/08/26/post/e01efade.html
作者
Egg_laying_master
发布于
2025年8月26日
许可协议