概率期望 FFT bzoj 3451 Tyvj1953 Normal

Posted foreverpiano

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了概率期望 FFT bzoj 3451 Tyvj1953 Normal相关的知识,希望对你有一定的参考价值。

http://www.lydsy.com/JudgeOnline/problem.php?id=3451

一个点对于答案的贡献就是他在点分树上的深度
对于一个点对\(u, v\)
\(u\)\(v\) 有贡献当且仅当在\(u\) -> \(v\)路径上先选了\(u\)
由于路径上的点被选到的概率相同
答案就是
\[\sum_{i=1}^{n}\sum_{j=1}^{n}\frac{1}{dis(i, j)}\]

然后点分治FFT就好了
复杂度\(O(n\; {\log n}^2)\)

#include<bits/stdc++.h>
#define lb long double 
#define fo(i, n) for(int i = 1; i <= (n); i ++)
#define out(x) cerr << #x << " = " << x << "\n"
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); ++ it)
using namespace std;
// by piano
template<typename tp> inline void read(tp &x) {
  x = 0; char c = getchar(); bool f = 0;
  for(; c < '0' || c > '9'; f |= (c == '-'), c = getchar());
  for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
  if(f) x = -x;
}
template<typename tp> inline void arr(tp *a, int n) {
  for(int i = 1; i <= n; i ++)
    cout << a[i] << " ";
  puts("");
}
const int N = 3e4 + 233;
const int M = N;
int ans[N];
namespace FFT {
  const int N = 3e5 + 233;
  const lb pi = acos(-1.0);
  struct cpx {
    lb a, b;
    cpx(lb _a = 0, lb _b = 0) {
      a = _a; b = _b;
    }
  }a[N];
  cpx operator + (const cpx &a, const cpx &b) {
    return cpx(a.a + b.a, a.b + b.b);
  }
  cpx operator - (const cpx &a, const cpx &b) {
    return cpx(a.a - b.a, a.b - b.b);
  }
  cpx operator * (const cpx &a, const cpx &b) {
    return cpx(a.a * b.a - a.b * b.b, a.a * b.b + a.b * b.a);
  }
  int n, rev[N], x, L = -1;
  inline void fft(cpx *a, int fff) {
    for(int i = 0; i < n; i ++) if(i < rev[i]) swap(a[i], a[rev[i]]);
    for(int l = 2; l <= n; l <<= 1) {
      cpx wn = cpx(cos(2 * pi / l), sin(2 * pi / l * fff));
      for(int j = 0, m = l >> 1; j < n; j += l) {
        cpx w(1, 0);
        for(int k = 0; k < m; k ++, w = w * wn) {
          cpx x = a[j + k], y = w * a[j + k + m];
          a[j + k] = x + y;
          a[j + k + m] = x - y;
        }
      }
    }
    if(fff == -1) {
      for(int i = 0; i < n; i ++)
        a[i].a /= n;
    }
  }

  inline void init(int m) {
    L = -1;
    for(n = 1; n <= m + 1; n <<= 1) L ++;
    memset(a, 0, sizeof(cpx) * (n + 2));
    for(int i = 0; i < n; i ++)
      rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << L);
  }

  inline void U(int pos, int val) {
    a[pos].a += val;
  }

  inline void doit(int fff) {
    fft(a, 1);
    for(int i = 0; i < n; i ++)
      a[i] = a[i] * a[i];
    fft(a, -1);
    for(int i = 0; i < n; i ++)
      ans[i] = ans[i] + fff * ((int) (a[i].a + 0.5));
  }
}

struct E {
  int nxt, to;
}e[M << 1];
int head[N], e_cnt = 0;
int f[N], sz[N], rt = 0, all, dep[N], book[N];
int n, m;
inline void add(int u, int v) {
  e[++ e_cnt] = (E) {head[u], v}; head[u] = e_cnt;
}

inline void frt(int u, int fat) {
  f[u] = 0; sz[u] = 1;
  for(int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    if(v == fat || book[v]) continue;
    frt(v, u);
    sz[u] += sz[v];
    f[u] = max(f[u], sz[v]);
  }
  f[u] = max(f[u], all - sz[u]);
  if(!rt || f[rt] > f[u]) rt = u;
}

vector<int> vec;
inline void dfs(int u, int fat) {
  vec.push_back(dep[u] = dep[fat] + 1);
  FFT::U(dep[u], 1);
  for(int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    if(v == fat || book[v]) continue;
    dfs(v, u);
  }
}

inline void cal(int u, int fff, int init) {
  vec.clear();
  int now = sz[u];
  FFT::init(now * 2);
  dep[0] = init - 1;
  dfs(u, 0);
  FFT::doit(fff);
}

inline void work(int u, int fat) {
  book[u] = 1; cal(u, 1, 0);
  for(int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    if(v == fat || book[v]) continue;
    cal(v, -1, 1);
    all = sz[v];
    frt(v, rt = 0);
    work(rt, u);
  }
}

inline void doit(void) {
  lb res = 0;
  for(int i = 0; i <= n; i ++)
    res += ans[i] * 1.0 / (i + 1);
  printf("%.4f\n", (double)res);
}

main(void) {
  read(n);
  for(int i = 1; i <= n - 1; i ++) {
    int x, y; read(x); read(y);
    ++ x; ++ y;
    add(x, y); add(y, x);
  }
  all = n;
  frt(1, rt = 0);
  work(rt, 0);
  doit();
}

以上是关于概率期望 FFT bzoj 3451 Tyvj1953 Normal的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3451Tyvj1953 Normal 点分治+FFT+期望

bzoj3451Tyvj1953 Normal 期望+树的点分治+FFT

3451: Tyvj1953 Normal 点分治 FFT

Bzoj 3450: Tyvj1952 Easy 期望/概率,动态规划

BZOJ-3450Tyvj1952Easy 概率与期望DP

BZOJ 3450: Tyvj1952 Easy [DP 概率]