HDU 5136 【2014广州现场赛 J】 Yue Fei's Battle

来源:互联网 发布:关于人工智能的书籍 编辑:程序博客网 时间:2024/04/30 03:04

http://acm.hdu.edu.cn/showproblem.php?pid=5136

题意

最长链为k的度<=3的无标号树个数

题解

  1. 若k为奇数,我们取最长链的中心,连出>=2个深度=[k/2]的二叉树。即
    (CA([k/2])2+CA([k/2])1))×S([k/2]1)+(CA([k/2])3+2CA([k/2])2+CA([k/2])1)
  2. 若k为偶数数,我们在最长链的中间假想一个虚拟点,连出2个深度=k/2的二叉树。即
    (CA(k/2)2+CA(k/2)1)

    其中A(n)为深度为n的二叉树个数,S(n)为A(n)部分和。同理对深度为n的二叉树,根连出>=1个深度为n-1的二叉树。
    A(n)=A(n1)×S(n2)+(CA(n1)2+CA(n1)1)

code

//by wangtianyu#include <cstdio>typedef long long LL;const int mod = 1000000007;const int N = 101000;struct modn {    int n;    modn() { }    modn(LL x) { n = (x < 0 ? (((x%mod)+mod)%mod) : x%mod); }    void print() const { printf("%d\n", n); }};modn operator +(const modn& A, const modn& B) { return A.n+B.n; }modn operator -(const modn& A, const modn& B) { return A.n-B.n; }modn operator *(const modn& A, const modn& B) { return (LL)A.n*B.n; }modn power(const modn& a, LL n) {    modn s = 1, t = a;    for (; n; n >>= 1) {        if (n&1) s = s * t;        t = t * t;    }    return s;}const modn inv2 = power(2, mod-2);const modn inv6 = power(6, mod-2);modn g[N], s[N];modn C3(modn x) {    if (x.n < 3) return 0;    return x * (x - 1) * (x - 2) * inv6;}modn C2(modn x) {    if (x.n < 2) return 0;    return x * (x - 1) * inv2;}int main() {    int n;    while(scanf("%d", &n) != EOF && n) {        g[0] = g[1] = 1;        s[0] = 1;        s[1] = 2;        for (int i = 2; i <= n; i ++)            g[i] = C2(g[i - 1]) + g[i - 1] + g[i - 1] * s[i - 2], s[i] = s[i - 1] + g[i];        modn ans;        if (n & 1) {            n = n / 2;            ans = C3(g[n]) + g[n] * g[n] + (C2(g[n]) + g[n]) * s[n - 1];        } else {            n = n / 2;            ans = C2(g[n]) + g[n];        }        ans.print();    }    return 0;}
0 0
原创粉丝点击