传送门

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

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

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

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

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

可以考虑容斥,枚举一个集合\(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\)次,减掉就好了

  1. //minamoto
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
  5. #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
  6. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  7. using namespace std;
  8. char buf[1<<21],*p1=buf,*p2=buf;
  9. inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
  10. int read(){
  11. R int res,f=1;R char ch;
  12. while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
  13. for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
  14. return res*f;
  15. }
  16. char sr[1<<21],z[20];int C=-1,Z=0;
  17. inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
  18. void print(R int x){
  19. if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
  20. while(z[++Z]=x%10+48,x/=10);
  21. while(sr[++C]=z[Z],--Z);sr[++C]='\n';
  22. }
  23. const int N=5e5+5,P=998244353;
  24. inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
  25. inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
  26. inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
  27. int ksm(R int x,R int y){
  28. R int res=1;
  29. for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
  30. return res;
  31. }
  32. struct eg{int v,nx;}e[N<<1];int head[N],tot;
  33. inline void add_edge(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
  34. int inv[N],sum[N],dep[N],fa[N],deg[N],st[N];
  35. int n,tmp,res,u,v,len,m,top,s,ans;
  36. void dfs(int u,int fat,int &x){
  37. fa[u]=fat,dep[u]=dep[fat]+1;
  38. if(dep[u]==len/2)++x;
  39. go(u)if(v!=fat)dfs(v,u,x);
  40. }
  41. int main(){
  42. // freopen("testdata.in","r",stdin);
  43. n=read();
  44. fp(i,1,n-1){
  45. u=read(),v=read(),add_edge(u,v),add_edge(v,u);
  46. ++deg[u],++deg[v];
  47. }
  48. int rt=1,tl=1;
  49. dfs(1,0,tmp);
  50. fp(i,1,n){
  51. if(dep[i]>dep[rt])rt=i;
  52. if(deg[i]==1)++m;
  53. }
  54. dfs(rt,0,tmp);
  55. fp(i,1,n)if(dep[i]>dep[tl])tl=i;
  56. len=dep[tl];
  57. inv[1]=1,sum[1]=m;
  58. fp(i,2,n){
  59. inv[i]=1ll*inv[P%i]*(P-P/i)%P;
  60. sum[i]=add(sum[i-1],mul(m,inv[i]));
  61. }
  62. if(len&1){
  63. int x=0;
  64. for(R int i=tl;i;i=fa[i])if(dep[i]==((len+1)>>1))x=i;
  65. dep[x]=0;
  66. go(x){
  67. dfs(v,x,tmp=0);
  68. if(tmp)st[++top]=tmp,s+=tmp;
  69. }
  70. }else{
  71. int x1=0,x2=0;
  72. for(R int i=tl;i;i=fa[i]){
  73. if(dep[i]==(len>>1))x1=i;
  74. if(dep[i]==(len>>1)+1)x2=i;
  75. }
  76. dep[x2]=0,dfs(x1,x2,st[++top]);
  77. dep[x1]=0,dfs(x2,x1,st[++top]);
  78. s=st[1]+st[2];
  79. }
  80. fp(i,1,top)ans=add(ans,sum[s-st[i]]);
  81. printf("%d\n",dec(ans,mul(top-1,sum[s])));
  82. return 0;
  83. }

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. 开发笔记--java.lang.OutOfMemoryError: PermGen space异常处理

    第一次到公司开发项目,比起之前的小项目来说这次的项目特别大,以至于运行之后出现了java.lang.OutOfMemoryError: PermGen space的异常,从字面意思上来看是内存溢出的原 ...

  2. Java for LeetCode 114 Flatten Binary Tree to Linked List

    Given a binary tree, flatten it to a linked list in-place. For example, Given 1 / \ 2 5 / \ \ 3 4 6 ...

  3. String源码中hashCode算法

    针对java中String源码hashcode算法源码分析 /** The value is used for character storage. */ private final char val ...

  4. jQuery/CSS3实现Android Dock效果

    在线演示 本地下载

  5. R语言快捷键

    一.控制台 功能  Windows & Linux   Mac 移动鼠标到控制台 Ctrl+2 Ctrl+2 移动到鼠标命令编辑 Ctrl+1 Ctrl+1 控制台清屏 Ctrl+L Comm ...

  6. html5--2.4新的布局元素(3)-section

    html5--2.4新的布局元素(3)-section 学习要点 了解section元素的语义和用法 通过实例理解section元素的用法 article元素和section元素的区别和共同点 art ...

  7. SENet(Squeeze-and-Excitation Networks)算法笔记---通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征

    Momenta详解ImageNet 2017夺冠架构SENet 转自机器之心专栏 作者:胡杰 本届 CVPR 2017大会上出现了很多值得关注的精彩论文,国内自动驾驶创业公司 Momenta 联合机器 ...

  8. 理解多线程中的ManualResetEvent(C#)

    线程是程序中的控制流程的封装.你可能已经习惯于写单线程程序,也就是,程序在它们的代码中一次只在一条路中执行.如果你多弄几个线程的话,代码运行可能会更加“同步”.在一个有着多线程的典型进程中,零个或更多 ...

  9. 数据可视化入门之show me the numbers

           数据的可视化一直是自己瞎玩着学,近来想系统的学数据可视化的东西,于是搜索资料时看到有人推荐<show me the numbers>作为入门. 由于搜不到具体的书籍内容,只能 ...

  10. [CTSC 2012] Cheat

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2806 [算法] 首先建立广义后缀自动机 注意到问题具有单调性 , 不妨对于每组询问二 ...