zoukankan      html  css  js  c++  java
  • [ZJOI2010]排列计数

    好题,看出来实际是个堆的种数,忘了组合数。。

    /**
     * Problem:Magic
     * Author:Shun Yao
     * Time:2013.6.2
     * Result:Accepted
     * Memo:DP, Math
     */
    
    #include <cstdio>
    #include <cmath>
    
    const long Maxn = 1000005;
    
    long min(long x, long y) {
    	return x < y ? x : y;
    }
    
    long n;
    long long p, f[Maxn], d[Maxn], jc[Maxn];
    
    void exgcd(long long a, long long b, long long &x, long long &y) {
    	if (!b) {
    		x = 1;
    		y = 0;
    	} else {
    		exgcd(b, a % b, y, x);
    		y -= a / b * x;
    	}
    }
    
    long long mulinv(long long X) {
    	long long x, y;
    	exgcd(X, p, x, y);
    	return ((-x) / p * p + x + p) % p;
    }
    
    int main() {
    	long i, dep, u, l, r;
    	freopen("magic.in", "r", stdin);
    	freopen("magic.out", "w", stdout);
    	scanf("%ld%lld", &n, &p);
    	jc[0] = 1;
    	for (i = 1; i <= n; ++i)
    		jc[i] = jc[i - 1] * i % p;
    	f[0] = f[1] = d[0] = d[1] = 1 % p;
    	for (i = 2; i <= n; ++i) {
    		dep = (long)(log(i) / log(2) + 1e-10);
    		u = (long)(pow(2.0, dep) + 1e-10) - 1;
    		l = ((u - 1) >> 1) + min(i - u, ((u + 1) >> 1));
    		r = i - 1 - l;
    		f[i] = f[l] * f[r] % p * jc[i - 1] % p;
    		d[i] = d[l] * d[r] % p * jc[l] % p * jc[r] % p;
    	}
    	printf("%lld", f[n] * mulinv(d[n]) % p);
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    球自由降落问题
    三次握手、四次挥手
    basicjava
    socket编程
    scanner和BufferedReader
    parseInt和valueOf
    正则表达式
    ASCII码常用值
    最大公约和最小公倍数
    查询语句
  • 原文地址:https://www.cnblogs.com/hsuppr/p/3115499.html
Copyright © 2011-2022 走看看