Codeforces 1236F - Alice and the Cactus(期望+分类讨论)
期望好题。
首先拆方差:
&E((x-E(x))^2)\\
=&E(x^2)-2E(x)E(E(x))+E(E(x)^2)\\
=&E(x^2)-E(x)^2
\end{aligned}
\]
因此我们只需 \(E(x^2)\) 和 \(E(x)\) 即可求解出答案。
考虑 \(x\) 是什么东西。直接从连通块个数的角度下手异常棘手。不过注意到原图是一个仙人掌,因此假设点数、边数、环数分别为 \(a,b,c\),那么连通块个数 \(x=a-b+c\),这可以看作原本有 \(a\) 个连通块,每加入一条边会少一个连通块,但有 \(c\) 次加边时成环,连通块个数不变。
因此 \(E(x^2)=E((a-b+c)^2)=E(a^2)+E(b^2)+E(c^2)-2E(ab)+2E(ac)-2E(bc)\),\(E(x)=E(a)-E(b)+E(c)\)。
考虑对这九个东西分别计算:
1. \(E(a)\)
显然 \(E(a)=\dfrac{n}{2}\)
2. \(E(b)\)
显然 \(E(b)=\dfrac{m}{4}\),因为每条边有 \(\dfrac{1}{4}\) 的概率存在。
3. \(E(c)\)
假设原仙人掌中第 \(i\) 个环点数为 \(C_i\),那么显然第 \(i\) 个环被保留的概率就是 \(p_i=\dfrac{1}{2^{C_i}}\)
期望环数 \(=\sum\limits_{i=1}^cp_i\),其中 \(c\) 为原仙人掌中环数。
4. \(E(a^2)\)
根据期望的线性性 \(E(a^2)\) 等于每对点同时存在的概率。
考虑对于两个点 \(i,j\):
- 如果 \(i=j\),那它们同时存在的概率为 \(\dfrac{1}{2}\)
- 否则它们同时存在的概率为 \(\dfrac{1}{4}\)
化简一下可得 \(E(a^2)=\dfrac{n(n+1)}{4}\)
5. \(E(b^2)\)
根据期望的线性性 \(E(b^2)\) 等于每对边同时存在的概率。
考虑两条边 \(i,j\):
- 如果 \(i=j\),那它们同时存在的概率为 \(\dfrac{1}{4}\)
- 如果 \(i,j\) 两条边恰好存在一个公共端点,那么它们同时存在的概率为 \(\dfrac{1}{8}\)
- 否则它们同时存在的概率为 \(\dfrac{1}{16}\)
对于第一种情况贡献就是 \(E(b)\),直接加上,对于第二种情况就枚举公共点,这样可以算得有多少对边符合第二种情况,剩余的边肯定都属于第三种情况了。
6. \(E(c^2)\)
根据期望的线性性 \(E(c^2)\) 等于每对环同时存在的概率。
考虑两个环 \(i,j\),由于原图是仙人掌两个不同的环最多只有一个公共点:
- 如果 \(i=j\),那它们同时存在的概率为 \(p_i\)
- 如果 \(i,j\) 两个环恰好存在一个公共点,那它们同时存在的概率为 \(p_i·p_j·2\)
- 否则它们同时存在的概率为 \(p_i·p_j\)
和 \(E(b^2)\) 的求法类似,第一种情况的贡献就是 \(E(c)\),对于二三两种情况我们先额外将所有 \(i\ne j\) 的 \(p_i·p_j\) 加入答案,再额外枚举所有符合第二类限制的两个环 \(i,j\),再将它们的 \(p_i·p_j\) 累加入答案。具体求法也是枚举公共点然后扫一遍,并维护当前扫过的所有环的 \(p_i\) 之和即可算出贡献。
7. \(E(ab)\)
根据期望的线性性 \(E(ab)\) 等于每个点与每条边同时存在的概率之和。
考虑一个点 \(a\) 和一条边 \(e\):
- 如果 \(a\) 是 \(e\) 的一个端点,那么它们同时存在的概率为 \(\dfrac{1}{4}\)
- 否则它们同时存在的概率为 \(\dfrac{1}{8}\)
枚举每个点,然后预处理每个点的度即可算出有多少条边符合第一种情况,有多少条边符合第二种情况。
8. \(E(ac)\)
根据期望的线性性 \(E(ac)\) 等于每个点与每个环同时存在的概率之和。
考虑一个点 \(a\) 和一个环 \(c\):
- 如果 \(a\) 在 \(c\) 上,那它们同时存在的概率为 \(p_c\)
- 否则它们同时存在的概率为 \(\dfrac{1}{2}p_c\)
还是按照套路枚举环 \(c\),预处理每个环上的点数即可知道有多少个点符合第一种情况,有多少个点符合第二种情况。
9. \(E(bc)\)
根据期望的线性性 \(E(bc)\) 等于每条边与每个环同时存在的概率之和。
考虑一条边 \(e\) 和一个环 \(c\):
- 如果 \(e\) 的两个端点都在 \(c\) 上,那它们同时存在的概率为 \(p_c\)
- 如果 \(e\) 的一个端点在 \(c\) 上,那它们同时存在的概率为 \(\dfrac{1}{2}p_c\)
- 如果 \(e\) 的两个端点都不在 \(c\) 上,那它们同时存在的概率为 \(\dfrac{1}{4}p_c\)
对于第一种情况还是通过预处理每个环上的点数即可快速算出,第二种情况符合条件的边数即为环上每个点的度数减 \(2\) 之和,剩余的边都是第三种情况。
时间复杂度 \(\mathcal O(n+m)\)。
const int MAXN=5e5;
const int MOD=1e9+7;
const int INV2=MOD+1>>1;
const int INV4=MOD+1>>2;
const int INV8=MOD+1>>3;
const int INV16=((MOD+9>>4)-INV2+MOD)%MOD;
int n,m,hd[MAXN+5],to[MAXN*2+5],nxt[MAXN*2+5],ec=0;
void adde(int u,int v){to[++ec]=v;nxt[ec]=hd[u];hd[u]=ec;}
int dfn[MAXN+5],fa[MAXN+5],tim=0,ipw2[MAXN+5];
vector<int> cyc[MAXN+5],bel[MAXN+5];
int cycnt=0,P[MAXN+5],deg[MAXN+5];
void dfs(int x){
dfn[x]=++tim;
for(int e=hd[x];e;e=nxt[e]){
int y=to[e];
if(!dfn[y]) fa[y]=x,dfs(y);
else if(dfn[y]<dfn[x]&&y!=fa[x]){
cycnt++;
for(int i=x;i^y;i=fa[i]) cyc[cycnt].pb(i),bel[i].pb(cycnt);
cyc[cycnt].pb(y);bel[y].pb(cycnt);
}
}
}
int Ea(){return 1ll*n*INV2%MOD;}
int Eb(){return 1ll*m*INV4%MOD;}
int Ec(){int sum=0;for(int i=1;i<=cycnt;i++) sum=(sum+P[i])%MOD;return sum;}
int Ex(){return (0ll+Ea()-Eb()+Ec()+MOD)%MOD;}
int Eaa(){return 1ll*n*(n+1)%MOD*INV4%MOD;}
int Ebb(){
ll tot=1ll*m*(m-1);int res=1ll*m*INV4%MOD;
for(int i=1;i<=n;i++){
tot-=1ll*deg[i]*(deg[i]-1);
res=(res+1ll*deg[i]*(deg[i]-1)%MOD*INV8)%MOD;
} res=(res+1ll*tot%MOD*INV16)%MOD;
return res;
}
int Ecc(){
ll tot=1ll*cycnt*(cycnt-1);int res=Ec(),sum=0;
for(int i=1;i<=cycnt;i++) res=(res+2ll*sum*P[i])%MOD,sum=(sum+P[i])%MOD;
for(int i=1;i<=n;i++){
int ssum=0;
for(int j:bel[i]) res=(res+2ll*ssum*P[j])%MOD,ssum=(ssum+P[j])%MOD;
} return res;
}
int Eab(){
int res=0;
for(int i=1;i<=n;i++) res=(res+1ll*INV4*deg[i]+1ll*INV8*(m-deg[i]))%MOD;
return res;
}
int Eac(){
int res=0,sm=Ec();
for(int i=1;i<=n;i++){
int ssum=0;
for(int j:bel[i]) ssum=(ssum+P[j])%MOD;
res=(0ll+res+ssum+1ll*INV2*(sm-ssum+MOD))%MOD;
} return res;
}
int Ebc(){
int res=0;
for(int i=1;i<=cycnt;i++) res=(res+1ll*P[i]*cyc[i].size())%MOD;
for(int i=1;i<=cycnt;i++){
int sum_ed=0,rst;
for(int j:cyc[i]) sum_ed+=deg[j]-2;
rst=m-cyc[i].size()-sum_ed;
res=(0ll+res+1ll*P[i]*INV2%MOD*sum_ed+1ll*P[i]*INV4%MOD*rst)%MOD;
} return res;
}
int sqr(int x){return 1ll*x*x%MOD;}
int main(){
scanf("%d%d",&n,&m);
for(int i=(ipw2[0]=1);i<=n;i++) ipw2[i]=1ll*ipw2[i-1]*INV2%MOD;
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);adde(u,v);adde(v,u);
deg[u]++;deg[v]++;
} dfs(1);for(int i=1;i<=cycnt;i++) P[i]=ipw2[cyc[i].size()];
// printf("%d\n",Ec());
printf("%d\n",((0ll+Eaa()+Ebb()+Ecc()-2ll*Eab()-2ll*Ebc()+2ll*Eac()-sqr(Ex()))%MOD+MOD)%MOD);
return 0;
}
Codeforces 1236F - Alice and the Cactus(期望+分类讨论)的更多相关文章
- CodeForces - 789B B. Masha and geometric depression---(水坑 分类讨论)
CodeForces - 789B 当时题意理解的有点偏差,一直wa在了14组.是q等于0的时候,b1的绝对值大于l的时候,当b1的绝对值大于l的时候就应该直接终端掉,不应该管后面的0的. 题意告诉你 ...
- [cf1236F]Alice and the Cactus
首先,我们要用到期望的一个性质: 对于两个随机变量$X$和$Y$(不需要相互独立),有$E(X+Y)=E(X)+E(Y)$ 另外,对于一个仙人掌,令$n$为点数,$m$为边数,$c$为简单环个数,$X ...
- Codeforces 521E - Cycling City(点双连通分量+分类讨论)
Codeforces 题面传送门 & 洛谷题面传送门 大家都是暴力找生成树然后跳路径,代码不到 50 行(暴论)的一说--好,那本蒟蒻决定提供一种代码 150 行,但复杂度也是线性的分类讨论做 ...
- Codeforces 685C - Optimal Point(分类讨论+乱搞)
Codeforces 题面传送门 & 洛谷题面传送门 分类讨论神题. 首先看到最大值最小,一眼二分答案,于是问题转化为判定性问题,即是否 \(\exists x_0,y_0,z_0\) 满足 ...
- Codeforces 1513F - Swapping Problem(分类讨论+乱搞)
Codeforces 题目传送门 & 洛谷题目传送门 简单题,难度 *2500 的 D2F,就当调节一下一模炸裂了的自闭的心情,稍微写写吧. 首先我看到这题的第一反应是分类讨论+数据结构,即枚 ...
- Codeforces 460D Little Victor and Set --分类讨论+构造
题意:从区间[L,R]中选取不多于k个数,使这些数异或和尽量小,输出最小异或和以及选取的那些数. 解法:分类讨论. 设选取k个数. 1. k=4的时候如果区间长度>=4且L是偶数,那么可以构造四 ...
- Educational Codeforces Round 63 (Rated for Div. 2) D. Beautiful Array 分类讨论连续递推dp
题意:给出一个 数列 和一个x 可以对数列一个连续的部分 每个数乘以x 问该序列可以达到的最大连续序列和是多少 思路: 不是所有区间题目都是线段树!!!!!! 这题其实是一个很简单的dp 使用的是分 ...
- 【树链剖分】【dfs序】【LCA】【分类讨论】Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground
一棵树,q次询问,每次给你三个点a b c,让你把它们选做s f t,问你把s到f +1后,询问f到t的和,然后可能的最大值是多少. 最无脑的想法是链剖线段树……但是会TLE. LCT一样无脑,但是少 ...
- Codeforces 1461F - Mathematical Expression(分类讨论+找性质+dp)
现场 1 小时 44 分钟过掉此题,祭之 大力分类讨论. 如果 \(|s|=1\),那么显然所有位置都只能填上这个字符,因为你只能这么填. scanf("%d",&n);m ...
随机推荐
- Redis 高阶数据类型重温
今天这个专题接着上一篇 Redis 的基本数据类型 继续讲解剩下的高阶数据类型:BitMap.HyperLogLog 和 GEO hash.这些数据结构的底层也都是基于我们前面说的 5 种 基本类型, ...
- 分库分表利器之Sharding Sphere(深度好文,看过的人都说好)
Sharding-Sphere Sharding-JDBC 最早是当当网内部使用的一款分库分表框架,到2017年的时候才开始对外开源,这几年在大量社区贡献者的不断迭代下,功能也逐渐完善,现已更名为 S ...
- Hadoop面试题(四)——YARN
1.简述hadoop1与hadoop2 的架构异同 1)加入了yarn解决了资源调度的问题. 2)加入了对zookeeper的支持实现比较可靠的高可用. 2.为什么会产生 yarn,它解决了什么问题, ...
- 力扣 - 剑指 Offer 53 - I. 在排序数组中查找数字 I
题目 剑指 Offer 53 - I. 在排序数组中查找数字 I 思路1 一般来说,首先想到的是使用一个变量,从头开始遍历整个数组,记录target数组出现的次数,但是这样的时间复杂度是O(n),还是 ...
- 热身训练4 Article
Article 在这个学期即将结束时,DRD开始写他的最后一篇文章. DRD使用著名的Macrohard的软件World来写他的文章. 不幸的是,这个软件相当不稳定,它总是崩溃. DRD需要在他的文章 ...
- Shadertoy 教程 Part 5 - 运用SDF绘制出更多的2D图形
Note: This series blog was translated from Nathan Vaughn's Shaders Language Tutorial and has been au ...
- Loto实践干货(8)loto示波器在LED台灯调光问题维修中的应用案例
Loto实践干货(8)loto示波器在LED台灯调光问题维修中的应用案例 一位客户最近觉得觉得他的LED台灯好闪, 于是拆了看看,里面的控制板是这样的: 干掉双色调光功能,只调亮度的话闪烁的状况能好转 ...
- c++ template 实现一个简单的"栈"
一: 实现一个简单的swap 原来我们写swap一定会这样写: 对于int类型的: swap(const int &x,const int &y) { int temp; temp = ...
- 装了这几个IDEA插件,基本上一站式开发了!
前言 前几天有社区小伙伴私聊我,问我都用哪些IDEA插件,我的IDEA的主题看起来不错. 作为一个开源作者,每周要code大量的代码,提升日常工作效率是我一直追求的,在众多的IDEA插件中,我独钟爱这 ...
- JMeter跨线程组保持登录(多线程组共享cookie)
使用__setProperty设置全局变量: 1.jmeter中创建一个登录请求,然后执行,察看结果树-->查看返回cookie信息,我的是在Response data中的 Response h ...