• bzoj3451 Normal


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

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

    这个

    注意这个写法有问题,随便来个菊花图就是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 = 30010, INF = 0x3f3f3f3f;
     18  
     19 inline void read(int &x) {
     20     x = 0;
     21     char c = getchar();
     22     while(c < '0' || c > '9') {
     23         c = getchar();
     24     }
     25     while(c >= '0' && c <= '9') {
     26         x = (x << 3) + (x << 1) + c - 48;
     27         c = getchar();
     28     }
     29     return;
     30 }
     31  
     32 struct cp {
     33     LD x, y;
     34     cp(LD X = 0, LD Y = 0) {
     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 * 4], b[N * 4];
     48  
     49 struct Edge {
     50     int nex, v;
     51 }edge[N << 1]; int tp;
     52  
     53 int r[N * 4], 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 = 0; i < n; i++) {
     66         if(i < r[i]) {
     67             std::swap(a[i], a[r[i]]);
     68         }
     69     }
     70     for(register int len = 1; len < n; len <<= 1) {
     71         cp Wn(cos(pi / len), f * sin(pi / len));
     72         for(register int i = 0; i < n; i += (len << 1)) {
     73             cp w(1, 0);
     74             for(register int j = 0; 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 == -1) {
     83         for(register int i = 0; 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 
    ");
     92     for(int i = 0; i <= n; i++) {
     93         printf("%d ", bin[i]);
     94     }
     95     printf("
    ");*/
     96     int lm = 1, len = 2;
     97     while(len <= n * 2) {
     98         len <<= 1;
     99         lm++;
    100     }
    101     for(register int i = 0; i <= len; i++) {
    102         r[i] = (r[i >> 1] >> 1) | ((i & 1) << (lm - 1));
    103     }
    104     for(register int i = 0; i <= n; i++) {
    105         a[i] = cp(bin[i], 0);
    106     }
    107     for(register int i = n + 1; i <= len; i++) {
    108         a[i] = cp(0, 0);
    109     }
    110     FFT(a, len, 1);
    111     for(register int i = 0; i <= len; i++) {
    112         a[i] = a[i] * a[i];
    113     }
    114     FFT(a, len, -1);
    115     /*for(int i = 0; i <= n + n; i++) {
    116         printf("%d ", (int)(a[i].x + 0.5));
    117     }
    118     printf("
    ");*/
    119     for(register int i = 0; 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] = 1;
    128     int large = -1;
    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] + 1;
    147     bin[d[x]]++;
    148     siz[x] = 1;
    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, 0, sizeof(int) * (last_n + 1));
    163     }
    164     small = INF;
    165     get_root(x, 0);
    166     if(f) {
    167         cal(last_n, -1);
    168     }
    169     x = root;
    170     memset(bin, 0, sizeof(int) * (_n + 1));
    171     DFS(x, 0);
    172     cal(_n, 1);
    173     del[x] = 1;
    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, 1, siz[x]);
    181     }
    182     return;
    183 }
    184  
    185 int main() {
    186     d[0] = -1;
    187     read(n);
    188     for(register int i = 1, x, y; i < n; i++) {
    189         read(x); read(y);
    190         add(x + 1, y + 1); add(y + 1, x + 1);
    191     }
    192  
    193     _n = n;
    194     div(1, 0, n);
    195     LD ans = 0;
    196     /*for(int i = 0; i <= n; i++) {
    197         printf("%d ", cnt[i]);
    198     }
    199     printf("
    ");*/
    200     for(register int i = 0; i < n; i++) {
    201         ans += (LD)cnt[i] / (i + 1);
    202     }
    203     printf("%.4Lf
    ", ans);
    204     return 0;
    205 }
    AC代码

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

  • 相关阅读:
    HTML DOM 12 表格排序
    HTML DOM 10 常用场景
    HTML DOM 10 插入节点
    HTML DOM 09 替换节点
    HTML DOM 08 删除节点
    HTML DOM 07 创建节点
    022 注释
    024 数字类型
    005 基于面向对象设计一个简单的游戏
    021 花式赋值
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10414474.html
Copyright © 2020-2023  润新知