zoukankan      html  css  js  c++  java
  • [HNOI2008]明明的烦恼

    根据prufer序列可以一一对应无根树。

    一个度数为(n)的会出现(n - 1)次,然后组合数算一算就好了。

    注意高精度

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
     
    int n, t;
    const int MAXN = 5010;
    typedef long long LL;
    const int DX = 1000000;
    struct N {
        int sum[MAXN], dig;
        void mul(int x) {
            for (int i = 0; i != dig; ++i) sum[i] *= x;
            for (int i = 0; i != dig + 5; ++i) {
                sum[i + 1] += sum[i] / DX;
                sum[i] %= DX;
            }
            dig += 5;
            while (!sum[dig - 1]) --dig;
        }
        void div(int x) {
            int now = 0;
            for (int i = dig - 1; ~i; --i) {
                now = now * DX + sum[i];
                sum[i] = now / x;
                now %= x;
            }
            while (!sum[dig - 1]) --dig;
        }
        void print() {
            printf("%d", sum[dig - 1]);
            for (int i = dig - 2; ~i; --i)
                printf("%06d", sum[i]);
            putchar(10);
        }
    } a;
    int main() {
        scanf("%d", &n);
        a.sum[0] = 1; a.dig = 1;
        for (int i = 2; i <= n - 2; ++i)
            a.mul(i);
        int lst = n - 2, cnt = 0;
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &t);
            cnt += t == -1;
            if (t < 0) continue;
            lst -= t - 1;
            for (int j = t - 1; j > 1; --j)
                a.div(j);
        }
        if (lst < 0 || (cnt == 0 && lst != 0)) return puts("0"), 0;
        for (int i = 1; i <= lst; ++i) a.mul(cnt), a.div(i);
        a.print();
        return 0;
    }
    
  • 相关阅读:
    联考20200801 T2 皮卡丘
    联考20200729 T2 划愤
    联考20200801 T1 林海的密码
    联考20200725 T2 Tree
    联考20200721 T1 s1mple
    联考20200730 T2 小B的环
    联考20200730 T1 小B的班级
    联考20200718 T1 因懒无名
    联考20200723 T1 数
    联考20200722 T1 集合划分
  • 原文地址:https://www.cnblogs.com/daklqw/p/10361508.html
Copyright © 2011-2022 走看看