• BZOJ 1211[HNOI2004]树的计数


    描述

    一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵。给定n,d1, d2, …, dn,编程需要输出满足d(vi)=di的树的个数。

    题解

    每颗树都对应以中prufer数列, prufer数列中数出现的个数 $=$ 节点的度数 -1

    所以变成了求再prufer数列中, $x$出现次数为$c_x$ 的排列数

    答案为$!(N - 2) / prodlimits_{i = 1}^N{a_i-1}$

    直接算会爆LL, 需要分解质因数

     另外还需要特判

    代码

     我发现打了个错误程序,由于某B姓OJ数据太水竟然过了。。。这个是错误的→_→,幸好发现了, 不然要出锅QAQ

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define ll long long
     4 #define rd read()
     5 using namespace std;
     6 
     7 const int N = 200;
     8 
     9 int pri[N], tot, vis[N], n, cnt[N], sum;
    10 ll ans = 1;
    11 
    12 ll fpow(ll a, ll p) {
    13     ll re = 1;
    14     for(; p; p >>= 1, a = a * a) if(p & 1) re = re * a;
    15     return re;
    16 }
    17 
    18 int read() {
    19     int X = 0, p = 1; char c = getchar();
    20     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    21     for(; c >= '0' && c <= '9'; c = getchar()) X = X  * 10 + c - '0';
    22     return X * p;
    23 }
    24 
    25 void init() {
    26     for(int i = 2; i < N; ++i) {
    27         if(!vis[i]) pri[++tot] = i;
    28         for(int j = 1; j <= tot && pri[j] * i < N; ++j) {
    29             vis[i * pri[j]] = 1;
    30             if(i % pri[j] == 0) break;
    31         }
    32     }
    33 }
    34 
    35 void cal(int x, int k) {
    36     if(!x || x == 0) return;
    37     for(int i = 1; i <= tot && x != 1; ++i) if(x % pri[i] == 0) {
    38         while(x % pri[i] == 0) cnt[i] += k, x /= pri[i];
    39     }
    40 }
    41 
    42 int main()
    43 {
    44     init();
    45     n = rd;
    46     for(int i = 2; i <= n - 2; ++i) cal(i, 1);
    47     for(int i = 1; i <= n; ++i) {
    48         int x = rd;
    49         if(n != 1 && !x) return printf("0
    "), 0;
    50         if(n == 1 && x) return printf("0
    "), 0;
    51         if(n == 1 && !x) return printf("1
    "), 0;
    52         for(int j = 2; j < x; ++j) cal(j, -1);
    53         sum += x - 1;
    54     }
    55     if(sum != n - 2) return printf("0
    "), 0;
    56     for(int i = 1; i <= tot; ++i) ans *= fpow(pri[i], cnt[i]);
    57     printf("%lld
    ", ans);
    58 }
    View Code
  • 相关阅读:
    CSS之Position详解
    线性回归预测法linear regression
    置信区间
    asp.net MVC 中使用dataannotation验证Model
    决策树Decision Tree
    Net反射在项目中的应用
    C#并行编程并行任务
    一个特殊的产品价格制定法(市场决定价格)
    Json
    线性规划模型(线性优化模型)Linear programming
  • 原文地址:https://www.cnblogs.com/cychester/p/9509295.html
Copyright © 2020-2023  润新知