• 【BZOJ1005】[HNOI2008]明明的烦恼


    【BZOJ1005】[HNOI2008]明明的烦恼

    题面

    bzoj

    洛谷

    题解

    前置芝士:

    (prufer)序列

    戳这里

    关于此题

    设有度数限制的点的个数是(cnt),度数为(d[i]),令(sum=sum_{i=1}^{cnt}(d[i]-1))

    不同排列的个数为

    [C_{n-2}^{sum} imesfrac{sum!}{prod_{i=1}^{cnt}(d[i]-1)!} ]

    还剩下(n-2-sum)个位置放(n-cnt)个点,

    经过化简,最后的答案为

    [Ans=(n-cnt)^{n-2-sum} imesfrac{(n-2)!}{(n-2-sum)! imesprod_{i=1}^{cnt}(d[i]-1)!} ]

    然后要写高精qaq。

    (tips:)通过分解质因数避免高精除法。

    代码

    #include <iostream> 
    #include <cstdio> 
    #include <cstdlib> 
    #include <cstring> 
    #include <cmath> 
    #include <algorithm> 
    using namespace std; 
    inline int gi() { 
        register int data = 0, w = 1; 
        register char ch = 0; 
        while (!isdigit(ch) && ch != '-') ch = getchar(); 
        if (ch == '-') w = -1, ch = getchar(); 
        while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); 
        return w * data; 
    }
    const int BASE = 10000; 
    struct Wint { 
    	int num[2005], size; 
    	Wint() { memset(num, 0, sizeof(num)); size = 0; } 
    	void turn(int v) { size = 0; while (v) num[++size] = v % BASE, v /= BASE; } 
    	void write() { printf("%d", num[size]); for (int i = size - 1; i; i--) printf("%04d", num[i]); } 
    } ; 
    Wint operator * (const Wint &a, const int &b) { 
    	Wint c; 
    	for (int i = 1; i <= a.size; i++) c.num[i] = a.num[i] * b; 
    	for (int i = 1; i <= a.size; i++) c.num[i + 1] += c.num[i] / BASE, c.num[i] %= BASE; 
    	int tmp = a.size; 
    	while (c.num[tmp + 1]) ++tmp, c.num[tmp + 1] += c.num[tmp] / BASE, c.num[tmp] %= BASE; 
    	c.size = tmp;
    	return c; 
    } 
    const int MAX_N = 1e4 + 5; 
    int N, a[MAX_N], cnt, sum; 
    int p[MAX_N], p1[MAX_N], p2[MAX_N]; 
    void divisor(int *num, int x) { 
    	for (int i = 2; i * i <= x; i++)
    		while (x % i == 0) ++num[i], x /= i; 
    	if (x != 1) ++num[x]; 
    } 
    int main () {
    #ifndef ONLINE_JUDGE 
        freopen("cpp.in", "r", stdin); 
    #endif 
    	N = gi(); 
    	for (int i = 1; i <= N; i++) {
    		a[i] = gi(); if (a[i] == -1) continue; 
    		++cnt, sum += a[i] - 1; 
    	} 
    	if (sum > N - 2) return puts("0") & 0; 
    	for (int i = 1; i <= N - 2; i++) divisor(p1, i); 
    	for (int i = 1; i <= N - 2 - sum; i++) divisor(p2, i); 
    	for (int i = 1; i <= N; i++) {
    		if (a[i] == -1) continue; 
    		for (int j = 1; j < a[i]; j++) divisor(p2, j); 
    	} 
    	for (int i = 1; i <= N - 2 - sum; i++) divisor(p1, N - cnt); 
    	for (int i = 1; i <= N; i++) p[i] = p1[i] - p2[i]; 
    	Wint ans; 
    	ans.turn(1); 
    	for (int i = 1; i <= N; i++)
    		for (int j = 1; j <= p[i]; j++) ans = ans * i; 
    	ans.write();
    	putchar('
    '); 
    	return 0; 
    } 
    
  • 相关阅读:
    springboot拦截器的拦截配置和添加多个拦截器
    ASCII对照
    爬虫出现403错误解决办法
    PhantomJS在Selenium中被标记为过时的应对措施
    Selenium 之订制启动Chrome的选项(Options)
    Selenium+PhantomJS使用时报错原因及解决方案
    python爬虫之xpath的基本使用
    JSONObject类的引用必须jar包
    selenium之使用chrome浏览器测试(附chromedriver与chrome的对应关系表)
    PhantomJS 与python的结合
  • 原文地址:https://www.cnblogs.com/heyujun/p/10553365.html
Copyright © 2020-2023  润新知