传送门

数学还是太差了,想了半天都没想出来

首先有一个定理,如果直径(这里考虑经过的点数)为奇数,所有直径有同一个中点,如果直径为偶数,所有直径有同一条最中间的边。这个可以用反证法,假设不成立的话直径会变长

如果直径为奇数,那么我们可以以共同经过的那个点为根,把所有在直径上的叶子按不同的子树分类,如果某两个叶子在同一棵子树,那么它们不可能构成直径,如果在不同的子树,那么必定能构成直径。所以把所有在直径上的叶子按不同的子树分为若干个集合

如果是偶数,那么就直接分为两个集合

我们现在要求的,就是这些集合中只剩一个集合没有被完全染黑的期望时间

可以考虑容斥,枚举一个集合\(i\),让它成为没有被完全染黑的那个集合,那么我们现在只关心其它所有集合被全部染黑的时间,设\(m\)为叶子总数,\(s\)为剩下的集合中点的总数,设\(f_i\)为还剩下\(i\)个点没有被染色时染一个点的期望时间,那么有\(f_i=1+\frac{m-i}{m}f_i\),所以\(f_i=\frac{m}{i}\),那么剩下的集合全部被染色的时间就是\(\sum_{i=1}^{s}\frac{m}{i}\),预处理一下就可以了

然而按我们上面的枚举方法,有可能会有所有集合都被染黑的情况。考虑每一种所有集合都被染黑的方案,如果最后一个被染黑的集合黑了,那么其他集合肯定也黑了。所以每一个方案中每一个最后被染黑的集合会被其它所有集合枚举到\(t-1\)次(\(t\)为集合的个数),也就是说每一种全被染黑的方案会被统计\(t-1\)次,减掉就好了

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=5e5+5,P=998244353;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add_edge(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int inv[N],sum[N],dep[N],fa[N],deg[N],st[N];
int n,tmp,res,u,v,len,m,top,s,ans;
void dfs(int u,int fat,int &x){
fa[u]=fat,dep[u]=dep[fat]+1;
if(dep[u]==len/2)++x;
go(u)if(v!=fat)dfs(v,u,x);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read();
fp(i,1,n-1){
u=read(),v=read(),add_edge(u,v),add_edge(v,u);
++deg[u],++deg[v];
}
int rt=1,tl=1;
dfs(1,0,tmp);
fp(i,1,n){
if(dep[i]>dep[rt])rt=i;
if(deg[i]==1)++m;
}
dfs(rt,0,tmp);
fp(i,1,n)if(dep[i]>dep[tl])tl=i;
len=dep[tl];
inv[1]=1,sum[1]=m;
fp(i,2,n){
inv[i]=1ll*inv[P%i]*(P-P/i)%P;
sum[i]=add(sum[i-1],mul(m,inv[i]));
}
if(len&1){
int x=0;
for(R int i=tl;i;i=fa[i])if(dep[i]==((len+1)>>1))x=i;
dep[x]=0;
go(x){
dfs(v,x,tmp=0);
if(tmp)st[++top]=tmp,s+=tmp;
}
}else{
int x1=0,x2=0;
for(R int i=tl;i;i=fa[i]){
if(dep[i]==(len>>1))x1=i;
if(dep[i]==(len>>1)+1)x2=i;
}
dep[x2]=0,dfs(x1,x2,st[++top]);
dep[x1]=0,dfs(x2,x1,st[++top]);
s=st[1]+st[2];
}
fp(i,1,top)ans=add(ans,sum[s-st[i]]);
printf("%d\n",dec(ans,mul(top-1,sum[s])));
return 0;
}

uoj#351. 新年的叶子(概率期望)的更多相关文章

  1. UOJ#351. 新年的叶子 概率期望

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ351.html 题目传送门 - UOJ351 题意 有一个 n 个节点的树,每次涂黑一个叶子节点(度为 1 ...

  2. [UOJ#351]新年的叶子

    [UOJ#351]新年的叶子 试题描述 躲过了AlphaGo 之后,你躲在 SingleDog 的长毛里,和它们一起来到了AlphaGo 的家.此时你们才突然发现,AlphaGo 的家居然是一个隐藏在 ...

  3. UOJ#299. 【CTSC2017】游戏 线段树 概率期望 矩阵

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ299.html 前言 不会概率题的菜鸡博主做了一道概率题. 写完发现运行效率榜上的人都没有用心卡常数——矩阵怎么可以用数组 ...

  4. 「UOJ351」新年的叶子

    「UOJ351」新年的叶子 题目描述 有一棵大小为 \(n\) 的树,每次随机将一个叶子染黑,可以重复染,问期望染多少次后树的直径会缩小. \(1 \leq n \leq 5 \times 10^5\ ...

  5. 【BZOJ-1419】Red is good 概率期望DP

    1419: Red is good Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 660  Solved: 257[Submit][Status][Di ...

  6. uvalive 7331 Hovering Hornet 半平面交+概率期望

    题意:一个骰子在一个人正方形内,蜜蜂在任意一个位置可以出现,问看到点数的期望. 思路:半平面交+概率期望 #include<cstdio> #include<cstring> ...

  7. OI队内测试一【数论概率期望】

    版权声明:未经本人允许,擅自转载,一旦发现将严肃处理,情节严重者,将追究法律责任! 序:代码部分待更[因为在家写博客,代码保存在机房] 测试分数:110 本应分数:160 改完分数:200 T1: 题 ...

  8. 2016 多校联赛7 Balls and Boxes(概率期望)

    Mr. Chopsticks is interested in random phenomena, and he conducts an experiment to study randomness. ...

  9. 牛客网多校赛第9场 E-Music Game【概率期望】【逆元】

    链接:https://www.nowcoder.com/acm/contest/147/E 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...

随机推荐

  1. 解决MAC Appium设备连不上IOS的的问题'idevice_id' program is not installed

    解决MAC Appium设备连不上IOS的的问题 错误的: [XCUITest] The 'idevice_id' program is not installed. If you are runni ...

  2. wireshark 学习 3 display filter

    过滤信息,得到想要的帧进行分析. http://www.networkcomputing.com/networking/wifi-troubleshooting-using-wireshark/155 ...

  3. API的理解和使用——键管理

    核心知识点: 1.键重命名:rename和renamenx,使用renamenx时newkey必须不存在,重命名后会使用del删除原来的键,如果值比较大也会会造成阻塞. 2.随机返回一个值:rando ...

  4. 【Leetcode-easy】Palindrome Number

    思路:除和求余 取得首位和末尾 比较是否相等. public boolean isPalindrome(int x){ if(x<0){ return false; } int div=1; w ...

  5. 《机器学习实战》学习笔记第二章 —— K-近邻算法

    主要内容: 一.算法概述 二.距离度量 三.k值的选择 四.分类决策规则 五.利用KNN对约会对象进行分类 六.利用KNN构建手写识别系统 七.KNN之线性扫描法的不足 八.KD树 一.算法概述 1. ...

  6. Spring Boot2.0之 jar打包方式

    Jar类型打包方式 1.使用mvn celan  package 打包 2.使用java –jar 包名 war类型打包方式 1.使用mvn celan package 打包 2.使用java –ja ...

  7. python-多线程2-线程同步

    线程同步: 一个场景: 一个列表里所有元素都是0,线程A从后向前把所有元素改成1,而线程B负责从前往后读取列表并打印. 那么,可能线程A开始改的时候,线程B便来打印列表了,输出就变成一半0一半1,这就 ...

  8. leetcode 102 Binary Tree Level Order Traversal(DFS||BFS)

    Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...

  9. bzoj3312

    K个硬币,要买N个物品. 给定买的顺序,即按顺序必须是一路买过去,当选定买的东西物品序列后,付出钱后,货主是不会找零钱的.现希望买完所需要的东西后,留下的钱越多越好,如果不能完成购买任务,输出-1 $ ...

  10. 点阵字体显示系列之一:ASCII码字库的显示

    http://blog.csdn.net/subfate/article/details/6444578 起因: 早在阅读tslib源代码时就注意到里面有font_8x8.c和font_8x16.c两 ...