Live2D

Solution -「CF 1025G」Company Acquisitions

Description

  Link.

  n 个公司,每个公司可能独立或者附属于另一个公司。初始时,每个公司附属于 aiai=1 表示该公司独立)。不存在两级及以上的附属关系。每次事件随机选取两个独立的公司,使其中一个公司所拥有的附属公司全部独立,并且该公司成为另一个公司的附属。求使仅存在一个独立公司的期望操作次数。对 109+7 取模。

  n500

Solution

  奇怪的解题姿势增加了!

  记一个公司的势能函数 ϕ(i)=2si1,其中 si 为该公司拥有的结点个数。并记 ϕ(S) 为局面 S 的势能函数,有:

ϕ(S)=i=1nϕ(i)

  那么,结束局面 T 的势能函数 ϕ(T)=2n11

  考虑单次事件对势能的影响。对于局面 S 中一次作用在两个独立公司 u,v 上的事件,有:

(1)E(Δϕ)=E(ϕ(S))ϕ(S)(2)=12((2su1)+(2sv1))(2su11)(22v11)(3)=1+2(4)=1

  一次事件在期望意义下会让局面的势能 +1!所以期望事件个数就是势能的期望变化次数。即:

ϕ(T)ϕ(S)

  其中 S 是初始局面,T 即上文结束局面。输出这个值就好啦!

  复杂度 O(n)

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;
}
posted @   Rainybunny  阅读(113)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示