[题解][YZOJ50074] 小 C 的岛屿
仅仅是对 \(O(n^4)\) 做法的一个记录。
简要题意
有 \(N\) 座岛屿,初始时没有边。每座岛屿都有一个概率值 \(p_i\) 和一个大小为 \(s_i\) 友好列表 \(A_i\) 。
小 \(c\) 站在 \(1\) 号岛屿,依次执行以下操作:
\((1)\) 设现在在岛屿 \(x\),有 \(p_x\) 的概率产生一条图中尚未存在的随机无向边,不会产生自环。
\((2)\) 如果此时所有岛屿仍未联通,她会在当前点的友好列表中,等概率随机选择一个,走到那座岛屿上。并把不满意度增加 \(1\),然后重复 \((1)\)。否则就结束这个过程
求她的期望不满意度,对一个 \(10^9+7\) 取模.
\(n\le 50\).
解题思路
思考后不难发现,状态只与当前的位置,以及边数相关,那么可以设状态:
\(e(x,i)\) 表示现在位于点 \(x\),图还差 \(i\) 条边连通,已经走的期望步数。
则最终答案是:
\]
不难得到 \(e\) 之间的转移式:
\]
如果分层高斯消元是 \(O(n^5)\),考虑设 \(e(x,i)=c(x)+\sum b(x,y)\cdot e(y,i-1)\) 来递推解决。
带入转移式可得:
e(x,i)=1+\frac{1}{s_x}\sum_{x\rightarrow y}p_x\cdot e(y,i-1)+(1-p_x)\cdot (\sum_{z=1}^nc(y)+b(y,z)\cdot e(z,i-1))\\
e(x,i)=1+\frac{p_x}{s_x}\sum_{x\rightarrow y}e(y,i-1)+\frac{(1-p_x)}{s_x}\cdot \sum_{x\rightarrow y}(c(y)+\sum_{z=1}^nb(y,z)\cdot e(z,i-1))\\
e(x,i)=1+\frac{(1-p_x)}{s_x}\cdot \sum_{x\rightarrow y}^nc(y)+\frac{p_x}{s_x}\sum_{x\rightarrow y}e(y,i-1)+\frac{(1-p_x)}{s_x}\cdot \sum_{x\rightarrow y}\sum_{z=1}^nb(y,z)\cdot e(z,i-1)\\
\end{aligned}
\]
于是可以得到两个方程:
\]
\]
这样就可以在 \(O(n^4)\) 的高斯消元内得到所有的 \(b,c\),然后递推得到 \(e(1,i)\)。
接下来考虑如何计算恰好 \(i\) 条边连通的概率,其实要算的就是 \(n\) 个点 \(i\) 条边连通图的方案数。
这类问题的经典处理方式是用斯特林反演来容斥。
于是考虑划分连通块,不同块之间的边不能选择,同一块内的边可选可不选。
这样实际连通块为 \(t\) 的图会在连通块为 \(k\) 的图时算到 \(\begin{Bmatrix}t\\k\end{Bmatrix}\) 次,乘上系数 \((-1)^{k-1}(k-1)!\) ,求和得到连通图。
所以 \(i\) 条边, \(n\) 个点的连通图数量实际上为:
\]
其中 \(G\) 需要取遍所有的 \(n\) 个点的,划分成了若干连通块的,每个连通块内连成了完全图的图,\(c(G)\) 表示 \(G\) 的连通块数量,\(e(G)\) 表示 \(G\) 的边数。
设 \(dp_{i,j}\) 表示 \(i\) 个点,划分成了若干连通块,每个连通块内部连成完全图后边数和为 \(j\),的所有图带上容斥系数的 \((-1)^{c(G)-1}(c(G)-1)!\) 之和。
然后考虑一下怎么把系数带上。首先正常的选一个连通块, 然后固定一号连通块在最前面, 然后接着选的时候, 每次不区分选连通块的顺序。那么在转移的时候,考虑下一个连通块的东西是 \(k\),重标号的系数就是 \(\binom{i+k-1}{k}\),因为 1 号连通块不能乱排,那么就可以钦定 1 号连通块最前面那个点一直不参与重标号, 于是每种划分方式就会算 \((k-1)!\) 种。
这样可以 \(O(n^4)\) 计算出 \(dp_{n,i}\) ,然后 \(O(n^4)\) 直接算出 \(g_i\),表示 \(n\) 个点 \(i\) 条边的连通图个数。
namespace Gauss{
int n, a[N][N], b[N];
inline int get(int x){ return (LL) b[x] * qpow(a[x][x], mod - 2) % mod; }
void init(int m){
n = m;
lfor(i, 1, n) b[i] = 0;
lfor(i, 1, n) lfor(j, 1, n) a[i][j] = 0;
}
void solve(){
lfor(i, 1, n){
int inv = qpow(a[i][i], mod - 2);
lfor(j, 1, n) if(i != j){
int K = (LL) inv * a[j][i] % mod;
lfor(k, 1, n) MOD(a[j][k] -= (LL) K * a[i][k] % mod);
MOD(b[j] -= (LL) K * b[i] % mod);
}
}
}
}
using Gauss :: get;
using Gauss :: init;
using Gauss :: solve;
void get_coef(){
init(n);
lfor(x, 1, n){
Gauss :: b[x] = mod - 1;
Gauss :: a[x][x] = mod - 1;
int v = (LL) q[x] * qpow(s[x], mod - 2) % mod;
lfor(j, 1, s[x]) Gauss :: a[x][a[x][j]] = v;
}
solve();
lfor(x, 1, n) c[x] = get(x);
lfor(z, 1, n){
init(n);
lfor(x, 1, n){
int v = (LL) q[x] * qpow(s[x]) % mod;
if(lnk[x][z]) Gauss :: b[x] = Mod(-(LL) p[x] * qpow(s[x]) % mod);
Gauss :: a[x][x] = mod - 1;
lfor(y, 1, n) if(lnk[x][y]) Gauss :: a[x][y] = v;
}
solve();
lfor(x, 1, n) b[x][z] = get(x);
}
lfor(i, 1, m) lfor(x, 1, n){
lfor(y, 1, n) MOD(e[x][i] += (LL) b[x][y] * e[y][i - 1] % mod - mod);
MOD(e[x][i] += c[x] - mod);
}
}
void get_prob(){
lfor(i, 1, n) dp[i][C(i, 2)] = 1;
lfor(i, 1, n) lfor(j, 0, m) if(dp[i][j]) lfor(k, 1, n - i)
MOD(dp[i + k][j + C(k, 2)] += -(LL) dp[i][j] * C(i + k - 1, k) % mod);
lfor(i, 0, m) lfor(j, i, m)
MOD(g[i] += (LL) dp[n][j] * C(j, i) % mod - mod);
lfor(i, 1, m) g[i] = (LL) g[i] * qpow(C(m, i), mod - 2) % mod;
rfor(i, m, 1) MOD(g[i] -= g[i - 1]);
}
signed main(){
read(n), m = n * (n - 1) / 2;
lfor(i, 1, n) read(p[i]), q[i] = Mod(1 - p[i]);
lfor(i, 1, n){
read(s[i]), a[i] = new int[s[i] + 1];
lfor(j, 1, s[i]) read(a[i][j]), lnk[i][a[i][j]] = 1;
}
prep();
get_coef();
get_prob();
lfor(i, 1, m) MOD(Ans += (LL) e[1][i] * g[i] % mod - mod);
cout << Mod(Ans - 1) << endl;
return 0;
}
[题解][YZOJ50074] 小 C 的岛屿的更多相关文章
- 【题解】小X的AK计划
题目描述 虽然在小X的家乡,有机房一条街,街上有很多机房.每个机房里都有一万个人在切题.小X刚刷完CodeChef,准备出来逛逛.机房一条街有n个机房,第i个机房的坐标为xi,小X的家坐标为0.小X在 ...
- 题解 P3951 小凯的疑惑
P3951 小凯的疑惑 数论极菜的小萌新我刚看这题时看不懂exgcd做法的题解,后来在网上找到了一篇博客,感觉代码和推导都更加清新易懂,于是在它的基础上写了题解qwq 分析 两数互质,且有无限个,想到 ...
- 「题解」小 R 打怪兽 monster
本文将同步发布于: 洛谷博客: csdn: 博客园: 简书. 题目 题目描述 小 R 最近在玩一款游戏.在游戏中,小 R 要依次打 \(n\) 个怪兽,他需要打败至少 \(k\) 个怪兽才能通关.小 ...
- 【题解】小Z的袜子
期末考试结束了,来写写blog吧 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具 ...
- 联赛膜你测试20 T1 Simple 题解 && NOIP2017 小凯的疑惑 题解(赛瓦维斯特定理)
前言: 数学题,对于我这种菜B还是需要多磨啊 Simple 首先它问不是好数的数量,可以转化为用总数量减去是好数的数量. 求"好数"的数量: 由裴蜀定理得,如果某个数\(i\)不能 ...
- 【题解】小M的作物
题目戳我 \(\text{Solution:}\) 这题要求最大收获,可以转化为所有可能的收益减去最小割. 单个点很好连边 \((S\to pos\to T),\) 问题在于如何处理组合的点. 观察到 ...
- 【题解】 P1373 小a和uim之大逃离
题解 P1373 小a和uim之大逃离 传送门 一道dp好题 乍看此题,感觉要这样设计: \(dp(x)(y)(mod_{a})(mod_{uim})(0/1)\) , 但是我上午考试就MLE了,赶紧 ...
- bzoj5044: 岛屿生成
Description 小Q设计了一款2D游戏,它的地图建立在二维笛卡尔坐标系上.这个游戏最大的特色就是可以随机生成地图,但是 岛屿生成却给小Q带来了巨大的麻烦.一个岛屿可以看成一个恰好有n个顶点的简 ...
- 贪心(qwq)习题题解
贪心(qwq)习题题解 SCOI 题解 [ SCOI2016 美味 ] 假设已经确定了前i位,那么答案ans一定属于一个区间. 从高位往低位贪心,每次区间查找是否存在使此位答案为1的值. 比如6位数确 ...
随机推荐
- Java并发机制(6)--阻塞队列
Java并发编程:阻塞队列整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3933404.html 1.什么是阻塞队列 除了同步容器(Hashtable ...
- jvm-learning-概述
JVM整体结构: java代码的执行流程 JVM的架构模型 public class StackStruTest { public static void main(String[] args) { ...
- java-字节流-字符流
I/O叙述 FileOutputStream类字节输出流的介绍: 写入数据的原理 java程序-->JVM(java虚拟机)--->OS(操作系统)---->OS调用写数据的方法-- ...
- synchronized 和 ReentrantLock 的区别?
synchronized 是和 if.else.for.while 一样的关键字,ReentrantLock 是类, 这是二者的本质区别.既然 ReentrantLock 是类,那么它就提供了比 sy ...
- 为什么在重写 equals 方法的时候需要重写 hashCode 方法?
因为有强制的规范指定需要同时重写 hashcode 与 equal 是方法,许多容器类, 如 HashMap.HashSet 都依赖于 hashcode 与 equals 的规定.
- 学习Docker(一)
一.docker介绍 docker是半虚拟化,比完全虚拟化性能高,可以使用物理机性能100% Docker 镜像(Images): 用于创建 Docker 容器的模板 Docker 容器(Contai ...
- 攻防世界shrine
shrine import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os.environ.pop('FLAG' ...
- Linux中一切皆文件
谈一谈Linux中一切皆文件 1. Linux中所有内容都是以文件的形式保存和管理,即:一切皆文件. 普通文件是文件. 目录(在win下称为文件夹)是文件. 硬件设备(键盘.硬盘.打印机)是文件. 套 ...
- word中怎么加入endnote的插件
首先,打开Microsoft Word 2010,然后点击文件菜单,在弹出的项目中点击选项. 2 弹出Word选项对话框,在左侧导航处点击"加载项"按钮,如图. 3 在右侧内容窗口 ...
- 走在 SVG + Low Poly 的路上
随着 SVG 的发展,艺术家和设计师们把越来越多传统设计行业的东西引入了前端, low poly 就是其中之一.那 low poly 强大在哪呢,大家通过下面的图来感受一下. 恰巧我们产品 Logo ...