Dichromatic Trees
Posted tempestt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dichromatic Trees相关的知识,希望对你有一定的参考价值。
条件:
1:每个红色节点的儿子都是黑色节点
2.每个叶子到根路径上的黑点数相等,等于某个常数,称作树的black height
求给定black height和节点数的符合条件的方案数
$black_{h} = x (black_{h-1} + red_{h-1})^2$
$red_{h} = x black_{h}^2$
任意模数的fft
#include <bits/stdc++.h> using namespace std; #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i) #define dwn(i, j, k) for (int i = int(j); i >= int(k); -- i) typedef long long LL; const int MOD = 258280327; const int N = 1 << 18; const long double PI = acos(-1.); LL red[17][N], black[17][N], M = 32767; struct Complex { long double r, i; Complex(long double _r = 0, long double _i = 0) { r = _r; i = _i; } Complex operator + (const Complex &rhs) const { return Complex(r + rhs.r, i + rhs.i); } Complex operator - (const Complex &rhs) const { return Complex(r - rhs.r, i - rhs.i); } Complex operator * (const Complex &rhs) const { return Complex(r * rhs.r - i * rhs.i, r * rhs.i + i * rhs.r); } Complex operator / (long double b) const { return Complex(r / b, i / b); } }; int a[N], b[N], c[N]; Complex conj(Complex &a) { return Complex(a.r, -a.i); } void fft(Complex *a, int n, int t) { int k = 0; while ((1 << k) < n) k ++; rep(i, 0, n - 1) { int t = 0; rep(j, 0, k - 1) if ((i >> j) & 1) t |= (1 << (k - 1 - j)); if (i < t) swap(a[i], a[t]); } for (int l = 2; l <= n; l <<= 1) { int m = l >> 1; long double o = 2 * PI / l * t; Complex _w(cos(o), sin(o)); for (int i = 0; i < n; i += l) { Complex w(1, 0); rep(j, 0, m - 1) { Complex x = w * a[i + j + m]; a[i + j + m] = a[i + j] - x; a[i + j] = a[i + j] + x; w = w * _w; } } } if (t == -1) rep(i, 0, n - 1) a[i] = a[i] / n; } void Mul(int *A, int *B, int *C, int len, LL P) { for(int i = 0;i < len; ++i) (A[i] += P) %= P, (B[i] += P) %= P; static Complex a[N], b[N], Da[N], Db[N], Dc[N], Dd[N]; for(int i = 0;i < len; ++i) a[i] = Complex(A[i] & M, A[i] >> 15); for(int i = 0;i < len; ++i) b[i] = Complex(B[i] & M, B[i] >> 15); fft(a, len, 1); fft(b, len, 1); for(int i = 0;i < len; ++i) { int j = (len - i) & (len - 1); static Complex da, db, dc, dd; da = (a[i] + conj(a[j])) * Complex(0.5, 0); db = (a[i] - conj(a[j])) * Complex(0, -0.5); dc = (b[i] + conj(b[j])) * Complex(0.5, 0); dd = (b[i] - conj(b[j])) * Complex(0, -0.5); Da[j] = da * dc; Db[j] = da * dd; Dc[j] = db * dc; Dd[j] = db * dd; //顺便区间反转,方便等会直接用DFT代替IDFT } for(int i = 0;i < len; ++i) a[i] = Da[i] + Db[i] * Complex(0, 1); for(int i = 0;i < len; ++i) b[i] = Dc[i] + Dd[i] * Complex(0, 1); fft(a, len, 1); fft(b, len, 1); for(int i = 0;i < len; ++i) { int da = (LL) (a[i].r / len + 0.5) % P; //直接取实部和虚部 int db = (LL) (a[i].i / len + 0.5) % P; int dc = (LL) (b[i].r / len + 0.5) % P; int dd = (LL) (b[i].i / len + 0.5) % P; C[i] = (da + ((LL)(db + dc) << 15) + ((LL)dd << 30)) % P; } } int main() { red[0][1] = 1; red[0][0] = 1; int len1 = 1 << 17, len2 = 1 << 18; rep(h, 1, 16) { rep(i, 0, len1 - 1) a[i] = (black[h - 1][i] + red[h - 1][i]) % MOD, b[i] = a[i]; rep(i, len1, len2 - 1) a[i] = b[i] = 0; Mul(a, b, c, len2, MOD); rep(i, 1, len1) black[h][i] = c[i - 1]; rep(i, 0, len1 - 1) a[i] = black[h][i], b[i] = a[i]; rep(i, len1, len2 - 1) a[i] = b[i] = 0; Mul(a, b, c, len2, MOD); rep(i, 1, len1) red[h][i] = c[i - 1]; } rep(i, 1, len1) rep(j, 1, 16) { (red[j][i] += red[j - 1][i]) %= MOD; (black[j][i] += black[j - 1][i]) %= MOD; } // rep(i, 0, 10) cout << black[1][i] << ‘ ‘; cout << ‘ ‘; int k, H, n; scanf("%d%d", &k, &H); rep(i, 1, k) { scanf("%d", &n); cout << (red[H][n] + black[H][n]) % MOD << ‘ ‘; } }
以上是关于Dichromatic Trees的主要内容,如果未能解决你的问题,请参考以下文章
[C#] 说说表达式树 - Expression Trees
Spark MLlib速成宝典模型篇07梯度提升树Gradient-Boosted Trees(Python版)
CF 1529E. Trees of Tranquillity