题意:点分治每次随机选重心,求期望复杂度。

发现一次点分治的复杂度就是点分树上每个节点的子树大小之和。(并没有发现......)

这个

注意这个写法有问题,随便来个菊花图就是n2了。

每一层点分治的时候,时间复杂度决不能与上一层大小挂钩。

  1. /**************************************************************
  2. Problem: 3451
  3. Language: C++
  4. Result: Accepted
  5. Time:5548 ms
  6. Memory:8548 kb
  7. ****************************************************************/
  8.  
  9. #include <cstdio>
  10. #include <algorithm>
  11. #include <cstring>
  12. #include <cmath>
  13.  
  14. typedef long long LL;
  15. typedef long double LD;
  16. const LD pi = 3.1415926535897932384626;
  17. const int N = , INF = 0x3f3f3f3f;
  18.  
  19. inline void read(int &x) {
  20. x = ;
  21. char c = getchar();
  22. while(c < '' || c > '') {
  23. c = getchar();
  24. }
  25. while(c >= '' && c <= '') {
  26. x = (x << ) + (x << ) + c - ;
  27. c = getchar();
  28. }
  29. return;
  30. }
  31.  
  32. struct cp {
  33. LD x, y;
  34. cp(LD X = , LD Y = ) {
  35. x = X;
  36. y = Y;
  37. }
  38. inline cp operator +(const cp &w) const {
  39. return cp(x + w.x, y + w.y);
  40. }
  41. inline cp operator -(const cp &w) const {
  42. return cp(x - w.x, y - w.y);
  43. }
  44. inline cp operator *(const cp &w) const {
  45. return cp(x * w.x - y * w.y, x * w.y + y * w.x);
  46. }
  47. }a[N * ], b[N * ];
  48.  
  49. struct Edge {
  50. int nex, v;
  51. }edge[N << ]; int tp;
  52.  
  53. int r[N * ], n, e[N], small, root, d[N], bin[N], cnt[N], _n, siz[N];
  54. bool del[N];
  55.  
  56. inline void add(int x, int y) {
  57. tp++;
  58. edge[tp].v = y;
  59. edge[tp].nex = e[x];
  60. e[x] = tp;
  61. return;
  62. }
  63.  
  64. inline void FFT(cp *a, int n, int f) {
  65. for(register int i = ; i < n; i++) {
  66. if(i < r[i]) {
  67. std::swap(a[i], a[r[i]]);
  68. }
  69. }
  70. for(register int len = ; len < n; len <<= ) {
  71. cp Wn(cos(pi / len), f * sin(pi / len));
  72. for(register int i = ; i < n; i += (len << )) {
  73. cp w(, );
  74. for(register int j = ; j < len; j++) {
  75. cp t = a[i + len + j] * w;
  76. a[i + len + j] = a[i + j] - t;
  77. a[i + j] = a[i + j] + t;
  78. w = w * Wn;
  79. }
  80. }
  81. }
  82. if(f == -) {
  83. for(register int i = ; i <= n; i++) {
  84. a[i].x /= n;
  85. }
  86. }
  87. return;
  88. }
  89.  
  90. inline void cal(int n, int f) {
  91. /*printf("cal \n");
  92. for(int i = 0; i <= n; i++) {
  93. printf("%d ", bin[i]);
  94. }
  95. printf("\n");*/
  96. int lm = , len = ;
  97. while(len <= n * ) {
  98. len <<= ;
  99. lm++;
  100. }
  101. for(register int i = ; i <= len; i++) {
  102. r[i] = (r[i >> ] >> ) | ((i & ) << (lm - ));
  103. }
  104. for(register int i = ; i <= n; i++) {
  105. a[i] = cp(bin[i], );
  106. }
  107. for(register int i = n + ; i <= len; i++) {
  108. a[i] = cp(, );
  109. }
  110. FFT(a, len, );
  111. for(register int i = ; i <= len; i++) {
  112. a[i] = a[i] * a[i];
  113. }
  114. FFT(a, len, -);
  115. /*for(int i = 0; i <= n + n; i++) {
  116. printf("%d ", (int)(a[i].x + 0.5));
  117. }
  118. printf("\n");*/
  119. for(register int i = ; i <= len; i++) {
  120. cnt[i] += f * (int)(a[i].x + 0.5);
  121. }
  122. return;
  123. }
  124.  
  125. void get_root(int x, int f) {
  126. bin[d[x]]++;
  127. siz[x] = ;
  128. int large = -;
  129. for(int i = e[x]; i; i = edge[i].nex) {
  130. int y = edge[i].v;
  131. if(y == f || del[y]) {
  132. continue;
  133. }
  134. get_root(y, x);
  135. siz[x] += siz[y];
  136. large = std::max(large, siz[y]);
  137. }
  138. if(small > std::max(large, _n - siz[x])) {
  139. small = std::max(large, _n - siz[x]);
  140. root = x;
  141. }
  142. return;
  143. }
  144.  
  145. void DFS(int x, int f) {
  146. d[x] = d[f] + ;
  147. bin[d[x]]++;
  148. siz[x] = ;
  149. for(int i = e[x]; i; i = edge[i].nex) {
  150. int y = edge[i].v;
  151. if(y == f || del[y]) {
  152. continue;
  153. }
  154. DFS(y, x);
  155. siz[x] += siz[y];
  156. }
  157. return;
  158. }
  159.  
  160. void div(int x, int f, int last_n) {
  161. if(f) {
  162. memset(bin, , sizeof(int) * (last_n + ));
  163. }
  164. small = INF;
  165. get_root(x, );
  166. if(f) {
  167. cal(last_n, -);
  168. }
  169. x = root;
  170. memset(bin, , sizeof(int) * (_n + ));
  171. DFS(x, );
  172. cal(_n, );
  173. del[x] = ;
  174. for(int i = e[x]; i; i = edge[i].nex) {
  175. int y = edge[i].v;
  176. if(del[y]) {
  177. continue;
  178. }
  179. _n = siz[y];
  180. div(y, , siz[x]);
  181. }
  182. return;
  183. }
  184.  
  185. int main() {
  186. d[] = -;
  187. read(n);
  188. for(register int i = , x, y; i < n; i++) {
  189. read(x); read(y);
  190. add(x + , y + ); add(y + , x + );
  191. }
  192.  
  193. _n = n;
  194. div(, , n);
  195. LD ans = ;
  196. /*for(int i = 0; i <= n; i++) {
  197. printf("%d ", cnt[i]);
  198. }
  199. printf("\n");*/
  200. for(register int i = ; i < n; i++) {
  201. ans += (LD)cnt[i] / (i + );
  202. }
  203. printf("%.4Lf\n", ans);
  204. return ;
  205. }

AC代码

注意FFT里面j从0开始,到len。

bzoj3451 Normal的更多相关文章

  1. [BZOJ3451]normal 点分治,NTT

    [BZOJ3451]normal 点分治,NTT 好久没更博了,咕咕咕. BZOJ3451权限题,上darkbzoj交吧. 一句话题意,求随机点分治的期望复杂度. 考虑计算每个点对的贡献:如果一个点在 ...

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

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

  3. BZOJ3451 Normal 期望、点分治、NTT

    BZOJCH传送门 题目大意:给出一棵树,求对其进行随机点分治的复杂度期望 可以知道一个点的贡献就是其点分树上的深度,也就是这个点在点分树上的祖先数量+1. 根据期望的线性性,考虑一个点对\((x,y ...

  4. 【BZOJ3451】Normal

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

  5. 【BZOJ3451】Normal (点分治)

    [BZOJ3451]Normal (点分治) 题面 BZOJ 题解 显然考虑每个点的贡献.但是发现似乎怎么算都不好计算其在点分树上的深度. 那么考虑一下这个点在点分树中每一次被计算的情况,显然就是其在 ...

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

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

  7. BZOJ3451: Tyvj1953 Normal

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

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

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

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

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

随机推荐

  1. Flask_admin 笔记六 modelView的内置方法

    增加model后端Flask-Admin对与之配合的数据库模型做了一些假设. 如果要实现自己的数据库后端,并且Flask-Admin的模型视图仍可按预期工作,则应注意以下事项:1) 每一个model必 ...

  2. CSS 尺寸 (Dimension) 实例

    CSS 尺寸 (Dimension) 实例CSS 尺寸属性CSS 尺寸属性允许你控制元素的高度和宽度.同样,还允许你增加行间距. 属性 描述height 设置元素的高度.line-height 设置行 ...

  3. Mycat读写分离、主从切换、分库分表的操作记录

    系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...

  4. Oracle数据库设置为归档模式的操作方法

    Oracle归档模式非常非常重要!对于有些数据库刚装好后可能是非归档模式,这是很危险的!为了安全起见,一定要谨记:对于Oracle数据库,一定要设置为归档模式,尤其是生产库,只有这样才能实现数据库的有 ...

  5. nginx应用总结(1)-- 基础知识和应用配置梳理

    在linux系统下使用nginx作为web应用服务,用来提升网站访问速度的经验已五年多了,今天在此对nginx的使用做一简单总结. 一.nginx服务简介Nginx是一个高性能的HTTP和反向代理服务 ...

  6. haproxy反向代理环境部署(http和https代理)

    操作背景:前方有一台haproxy代理机器(115.100.120.57/192.168.1.7),后方两台realserver机器(192.168.1.150.192.168.1.151,没有公网i ...

  7. [2019BUAA软件工程]结对编程感想

    结对编程感想 写在前面   本博客为笔者在完成软件工程结对编程任务后对于编程过程.最终得分的一些感想与经验分享.此外笔者还对于本课程的结对编程部分提出了一些建议. Tips Link 作业要求博客 2 ...

  8. 关于QQ的NABCD模型

    关于QQ的NABCD模型 N--Need 随着电脑的普及,人们在网络上进行交流的时间越来越多,由于现有的交流工具还不是那么的完善,还不能够完全满足人们在交流时的需求.因此为了满足人们更多的需求,我们设 ...

  9. 剑指offer:树的子结构

    题目描述: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 解题思路: 同样考虑用递归来做. 利用两个递归函数,一个用于判断两棵树树否相等,另一个递归取A的 ...

  10. 5.2&5.3

    队友吕日荣 http://www.cnblogs.com/Russelling/ 最近队友有点忙,尽管如此,队友还是有很给力的付出,让我们在最后完成了任务. 一开始都不知道这次的任务是要做什么,毫无头 ...