zoukankan      html  css  js  c++  java
  • 「HNOI2008」明明的烦恼

    传送门

    这题的弱化版

    (prufer) 序列题。

    我们先考虑度数确定的点,记度数确定的点有 (k) 个,它们在 (prufer) 序列中一共出现 (cnt) 次。

    首先我们要从 (prufer) 序列的 (n - 2) 个位置中选 (cnt) 个来放这些点,然后我们考虑
    先不确定其它 (n - k) 个点的位置,此时方案数为:({n - 2 choose cnt}frac{cnt!}{prod_{d_i e-1} {(d_i - 1)!}})

    那么剩下 (n - k) 个点怎么处理呢?我们考虑把他们直接塞到剩下 (n - 2 - cnt) 个空中去就好了 (Q omega Q) ,方案数就是一个乘法原理:((n - k) ^ {n - 2 - cnt})

    最后的答案就是 ({n - 2 choose cnt}frac{cnt!}{prod_{d_i e-1} {(d_i - 1)!}}(n - k) ^ {n - 2 - cnt})

    稍微化简一下:

    [egin{aligned} ans & = {n - 2 choose cnt}frac{cnt!}{prod_{d_i e-1} {(d_i - 1)!}}(n - k) ^ {n - 2 - cnt} \ & = frac{(n - 2)!}{cnt! imes (n - 2 - cnt)!} imes frac{cnt!}{prod_{d_i e-1} {(d_i - 1)!}}(n - k) ^ {n - 2 - cnt} \ & = frac{(n - 2)!}{(n - 2 - cnt)! imes prod_{d_i e-1} {(d_i - 1)!}}(n - k) ^ {n - 2 - cnt} end{aligned} ]

    然后写个高精直接求就是了

    参考代码:

    #include <cstdio>
    #include <vector>
    using namespace std;
    
    const int _ = 1e3 + 5;
    
    struct BigInteger {
        vector < int > s;
        BigInteger() { s.clear(); }
        BigInteger clean() { while (s.size() && !s.back()) s.pop_back(); return *this; }
        BigInteger operator = (int x) {
            s.clear();
            while (x) s.push_back(x % 10), x /= 10;
            return this -> clean();
        }
        BigInteger operator * (const int& x) {
            int g = 0;
            for (int i = 0; i < s.size(); ++i) s[i] *= x;
            for (int i = 0; i < s.size(); ++i)
                s[i] += g, g = s[i] / 10, s[i] %= 10;
            while (g) s.push_back(g % 10), g /= 10;
            return this -> clean();
        }
        BigInteger operator / (const int& x) {
            int g = 0;
            for (int i = s.size() - 1; i >= 0; --i) {
                g = g * 10 + s[i];
                if (g >= x) s[i] = g / x, g %= x; else s[i] = 0;
            }
            return this -> clean();
        }
        void output() { for (int i = s.size() - 1; i >= 0; --i) printf("%d", s[i]); puts(""); }
    } ans;
    
    int n, k, s, d[_];
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("cpp.in", "r", stdin), freopen("cpp.out", "w", stdout);
    #endif
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) scanf("%d", d + i);
        if (n == 1) { puts(d[1] == -1 || d[1] == 0 ? "1" : "0"); return 0; }
        for (int i = 1; i <= n; ++i) if (d[i] != -1) ++k, s += d[i] - 1;
        if (s > n - 2) { puts("0"); return 0; }
        ans = 1;
        for (int i = 1; i <= n - 2; ++i) ans = ans * i;
        for (int i = 1; i <= n - 2 - s; ++i) ans = ans * (n - k);
        for (int i = 1; i <= n - 2 - s; ++i) ans = ans / i;
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= d[i] - 1; ++j) ans = ans / j;
        ans.output();
        return 0;
    }
    
  • 相关阅读:
    Android IOS WebRTC 音视频开发总结(五十)-- 技术服务如何定价?
    Android IOS WebRTC 音视频开发总结(四九)-- ffmpeg介绍
    Android IOS WebRTC 音视频开发总结(四八)-- 从商业和技术的角度看视频行业的机会
    Android IOS WebRTC 音视频开发总结(四七)-- 深度解读国内首届WebRTC大会背后的真相
    小程序缓存二开(带有效时间)
    小程序笔记五:页面数据传递
    小程序笔记四:表单提交form
    小程序笔记三:幻灯片swiper 和图片自定义高度
    小程序笔记二:部署
    小程序笔记一:基础设置
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/13096509.html
Copyright © 2011-2022 走看看