国际惯例的题面:

代价理解为重心和每个点这个点对的代价。根据期望的线性性,我们枚举每个点,计算会产生的ij点对的代价即可。
那么,i到j的链上,i必须是第一个被选择的点。
对于i来说,就是1/dis(i,j)。
所以答案就是sigma(i,j) 1/(dis(i,j)+1)。
然而这样计算是n^2的,考虑优化。
如果我们能计算出边长为某个数值的边的数量的话,是不是就能计算答案呢?
统计路径的题,一眼点分治。
考虑怎样计算,我们能dfs出每个子树中距离分治重心为x的点有多少个,然后我们枚举两个点让他们取去组成路径即可。
这显然是个卷积,FFT优化。我们补集转化,先计算全部方案,再减去本身对本身(两个点来自相同子树)的方案。
为什么这样算复杂度正确?因为当当前分治层数一定时,所有子树的最深点的深度总和是O(n)的,并且那个log还会更小。这样分析的话发现复杂度是O(nlog^2n)。
正常的二元关系计算方式是前缀和和当前的卷积贡献,为什么这次不能这样呢?
给你一棵扫把形的树,一半的点形成一条链,显然你会选择扫把的重心(一边是一堆叶子,一边是链)当做重心。
然后你发现链的那边长度为n/2,如果你对每个叶子都和链做一次卷积的话,恭喜你卡成n^2logn,不如暴力......

代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cmath>
  5. const int maxn=;
  6. const int inf=0x3f3f3f3f;
  7. const double pi = acos(-1.0);
  8.  
  9. int tim[maxn];
  10.  
  11. namespace FFT {
  12. struct Complex {
  13. double r,i;
  14. friend Complex operator + (const Complex &a,const Complex &b) { return (Complex){a.r+b.r,a.i+b.i}; }
  15. friend Complex operator - (const Complex &a,const Complex &b) { return (Complex){a.r-b.r,a.i-b.i}; }
  16. friend Complex operator * (const Complex &a,const Complex &b) { return (Complex){a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r}; }
  17. }cp[maxn];
  18. inline void FFT(Complex* dst,int n,int tpe) {
  19. for(int i=,j=;i<n;i++) {
  20. if( i < j ) std::swap(dst[i],dst[j]);
  21. for(int t=n>>;(j^=t)<t;t>>=) ;
  22. }
  23. for(int len=;len<=n;len<<=) {
  24. const int h = len >> ;
  25. const Complex per = (Complex){cos(pi*tpe/h),sin(pi*tpe/h)};
  26. for(int st=;st<n;st+=len) {
  27. Complex w = (Complex){1.0,0.0};
  28. for(int pos=;pos<h;pos++) {
  29. const Complex u = dst[st+pos] , v = dst[st+pos+h] * w;
  30. dst[st+pos] = u + v , dst[st+pos+h] = u - v , w = w * per;
  31. }
  32. }
  33. }
  34. if( !~tpe ) for(int i=;i<n;i++) dst[i].r /= n;
  35. }
  36. inline void mul(int* dst,int n) {
  37. int len = ;
  38. while( len <= ( n << ) ) len <<= ;
  39. for(int i=;i<len;i++) cp[i] = (Complex){(double)dst[i],0.0};
  40. FFT(cp,len,);
  41. for(int i=;i<len;i++) cp[i] = cp[i] * cp[i];
  42. FFT(cp,len,-);
  43. for(int i=;i<len;i++) dst[i] = (int)(cp[i].r+0.5);
  44. }
  45. }
  46.  
  47. namespace Tree {
  48. int s[maxn],t[maxn<<],nxt[maxn<<];
  49. int siz[maxn],mxs[maxn],ban[maxn];
  50. int su[maxn],tp[maxn];
  51.  
  52. inline void addedge(int from,int to) {
  53. static int cnt = ;
  54. t[++cnt] = to , nxt[cnt] = s[from] , s[from] = cnt;
  55. }
  56. inline void findroot(int pos,int fa,const int &fs,int &rt) {
  57. siz[pos] = , mxs[pos] = ;
  58. for(int at=s[pos];at;at=nxt[at]) if( t[at] != fa && !ban[t[at]] ) findroot(t[at],pos,fs,rt) , siz[pos] += siz[t[at]] , mxs[pos] = std::max( mxs[pos] , siz[t[at]] );
  59. if( ( mxs[pos] = std::max( mxs[pos] , fs - siz[pos]) ) <= mxs[rt] ) rt = pos;
  60. }
  61. inline void dfs(int pos,int fa,int dep,int &mxd) {
  62. mxd = std::max( mxd , dep ) , ++tp[dep];
  63. for(int at=s[pos];at;at=nxt[at]) if( t[at] != fa && !ban[t[at]] ) dfs(t[at],pos,dep+,mxd);
  64. }
  65. inline void solve(int pos,int fs) {
  66. int root = , mxd = , ths ;
  67. *mxs = inf, findroot(pos,-,fs,root) , ban[root] = ;
  68. for(int at=s[root];at;at=nxt[at]) if( !ban[t[at]]) {
  69. ths = , dfs(t[at],root,,ths) , mxd = std::max( mxd , ths );
  70. for(int i=;i<=ths;i++) su[i] += tp[i];
  71. FFT::mul(tp,ths);
  72. for(int i=;i<=ths<<;i++) tim[i] -= tp[i];
  73. memset(tp,,sizeof(int)*(ths<<|));
  74. }
  75. ++*su , FFT::mul(su,mxd);
  76. for(int i=;i<=mxd<<;i++) tim[i] += su[i];
  77. memset(su,,sizeof(int)*(mxd<<|));
  78. for(int at=s[root];at;at=nxt[at]) if( !ban[t[at]] ) solve(t[at],siz[t[at]]<siz[root]?siz[t[at]]:fs-siz[root]);
  79. }
  80. }
  81.  
  82. int main() {
  83. static int n;
  84. static long double ans;
  85. scanf("%d",&n);
  86. for(int i=,a,b;i<n;i++) scanf("%d%d",&a,&b) , ++a , ++b , Tree::addedge(a,b) , Tree::addedge(b,a);
  87. Tree::solve(,n) , ans = n;
  88. for(int i=;i<=n<<;i++) ans += (long double) tim[i] / ( i + );
  89. printf("%0.4Lf\n",ans);
  90. return ;
  91. }

ここでこのまま
即使在这里就这样
僕が消えてしまっても 誰も知らずに
我消失不见了 谁也不会知道吧
明日が来るのだろう
明天依然会来临吧
わずか 世界のひとかけらに過ぎない
我仅仅是 这个世界的微小碎屑
ひとりを夜が包む
夜晚怀抱孤独的身影

3451: Tyvj1953 Normal 点分治 FFT的更多相关文章

  1. BZOJ 3451: Tyvj1953 Normal 点分治+FFT

    根据期望的线性性,我们算出每个点期望被计算次数,然后进行累加. 考虑点 $x$ 对点 $y$ 产生了贡献,那么说明 $(x,y)$ 之间的点中 $x$ 是第一个被删除的. 这个期望就是 $\frac{ ...

  2. 【BZOJ3451】Tyvj1953 Normal 点分治+FFT+期望

    [BZOJ3451]Tyvj1953 Normal Description 某天WJMZBMR学习了一个神奇的算法:树的点分治!这个算法的核心是这样的:消耗时间=0Solve(树 a) 消耗时间 += ...

  3. 【BZOJ3451】Tyvj1953 Normal - 点分治+FFT

    题目来源:NOI2019模拟测试赛(七) 非原题面,题意有略微区别 题意: 吐槽: 心态崩了. 好不容易场上想出一题正解,写了三个小时结果写了个假的点分治,卡成$O(n^2)$ 我退役吧. 题解: 原 ...

  4. [BZOJ3451][Tyvj1953]Normal(点分治+FFT)

    https://www.cnblogs.com/GXZlegend/p/8611948.html #include<cmath> #include<cstdio> #inclu ...

  5. bzoj 3451: Tyvj1953 Normal [fft 点分治 期望]

    3451: Tyvj1953 Normal 题意: N 个点的树,点分治时等概率地随机选点,代价为当前连通块的顶点数量,求代价的期望值 百年难遇的点分治一遍AC!!! 今天又去翻了一下<具体数学 ...

  6. [BZOJ3451]Normal(点分治+FFT)

    [BZOJ3451]Normal(点分治+FFT) 题面 给你一棵 n个点的树,对这棵树进行随机点分治,每次随机一个点作为分治中心.定义消耗时间为每层分治的子树大小之和,求消耗时间的期望. 分析 根据 ...

  7. BZOJ3451 Tyvj1953 Normal 点分治 多项式 FFT

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3451.html 题目传送门 - BZOJ3451 题意 给定一棵有 $n$ 个节点的树,在树上随机点分 ...

  8. BZOJ3451: Tyvj1953 Normal

    题解: 好神的一道题.蒟蒻只能膜拜题解. 考虑a对b的贡献,如果a是a-b路径上第一个删除的点,那么给b贡献1. 所以转化之后就是求sigma(1/dist(i,j)),orz!!! 如果不是分母的话 ...

  9. 【bzoj3451】Tyvj1953 Normal 期望+树的点分治+FFT

    题目描述 给你一棵 $n$ 个点的树,对这棵树进行随机点分治,每次随机一个点作为分治中心.定义消耗时间为每层分治的子树大小之和,求消耗时间的期望. 输入 第一行一个整数n,表示树的大小接下来n-1行每 ...

随机推荐

  1. 【逆向工具】使用x64dbg+spy去除WinRAR5.40(64位)广告弹框

    1 学习目标 WinRAR5.40(64位)的弹框广告去除,由于我的系统为x64版本,所以安装了WinRAR(x64)版本. OD无法调试64位的程序,可以让我熟悉x64dbg进行调试的界面. 其次是 ...

  2. Linux 内核里的“智能指针”【转】

    转自:http://blog.jobbole.com/88279/ 众所周知,C/C++语言本身并不支持垃圾回收机制,虽然语言本身具有极高的灵活性,但是当遇到大型的项目时,繁琐的内存管理往往让人痛苦异 ...

  3. Python-CSS 基础

    css入门 一.架构分析 页面 => div的层级结构 => 具有采用哪些功能标签显示内容 结构层 > 位置层(布局层) > 内容层 二.css引入 - 行间式 <div ...

  4. vue系列之概念

    一.模板引擎 通常出现在应用层,即服务器端(MVC层中的view) 客户端HTTP请求->应用层的控制器(Controller)->应用层的服务层(Service,访问数据库)->封 ...

  5. 20个实用的webApp前端开发技巧

    自Iphone和Android这两个牛逼的手机操作系统发布以来,在互联网界从此就多了一个新的名词-WebApp(意为基于WEB形式的应用程序,运行在高端的移动终端设备). 开发者们都知道在高端智能手机 ...

  6. python for dl

    算是python的简明教程吧,总结的不错: https://zhuanlan.zhihu.com/p/24162430 python for opencv: https://zhuanlan.zhih ...

  7. 性能测试四:jmeter进阶之逻辑控制器

    常用的逻辑控制器 1,循环控制器:可以设置该控制器内的sampler执行的次数,循环次数与线程的循环次数各自独立 2,if控制器:根据判断条件决定是否执行该控制器内的请求,如果是字符串比较条件,参数和 ...

  8. js改变或添加className

    js改变或添加className <style type="text/css"> .newDiv { font-weight: bold; } </style&g ...

  9. 怎样在win7 IIS中部署网站?

    IIS作为微软web服务器的平台,可以轻松的部署网站,让网站轻而易举的搭建成功,那么如何在IIS中部署一个网站呢,下面就跟小编一起学习一下吧. 第一步:发布IIS文件 1:发布你所要在IIS上部署的网 ...

  10. String中根据,(逗号)进行分割

    package zhengze; public class StringTest07 { public static void main(String[] args) { String s = &qu ...