zoukankan      html  css  js  c++  java
  • [Luogu] P4071 [SDOI2016]排列计数

    (Link)

    Description

    多组询问,求有多少(1)(n)的排列(a),满足序列恰好有(m)个位置(i),使得(a_i = i)

    答案对(10^9 + 7)取模。

    Solution

    算是错排的板子题了。

    错排,就是对于某个(1sim{n})的排列,满足(forall{iin[1,n]},a_i e{i})

    那么这道题其实就是求(dbinom{n}{m}D(n-m))

    现在要解决如何求(D(n)),有两种方法求:

    首先是递推:对于一个错排(D(n)),不失一般性,考虑(1)这个数放在哪个位置。它肯定不能放在(a_1),剩下的位置随便放,所以先乘上一个(n-1)。然后再考虑(2)放在哪里:如果(2)放在(a_1),那么就是一个子问题(D(n-2));如果(2)不能放在(a_1),那(a_1)其实就相当于(a_2),这时是一个子问题(D(n-1))。综上,(D(n)=(n-1)(D(n-1)+D(n-2))),特别地,(D(0)=1,D(1)=0)

    其次是容斥: 正整数(1, 2, 3, …, n)的全排列有 (n!) 种,其中第(k)位是(k)的排列有((n-1)!)种;当(k)分别取(1, 2, 3, …, n)时,共有(dbinom{n}{1}*(n-1)!)种排列是至少放对了一个的,由于所求的是错排的种数,所以应当减去这些排列;但是此时把同时有两个数不错排的排列多排除了一次,应补上;在补上时,把同时有三个数不错排的排列多补上了一次,应排除......继续这一过程,得到错排的排列种数为

    (D(n)=sumlimits_{i=0}^n(-1)^idbinom{n}{i}(n-i)!)

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    
    const ll mod = 1e9 + 7;
    
    ll t, n, m, pw[1000005], inv[1000005], wp[1000005];
    
    ll read()
    {
    	ll x = 0; char ch = getchar();
    	while (ch < '0' || ch > '9') ch = getchar();
    	while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    	return x;
    }
    
    ll qpow(ll base, ll p)
    {
    	ll res = 1;
    	while (p)
    	{
    		if (p & 1) res = res * base % mod;
    		base = base * base % mod;
    		p >>= 1;
    	}
    	return res;
    }
    
    int main()
    {
    	t = read();
    	wp[0] = 1; wp[1] = 0; wp[2] = 1;
    	for (ll i = 3; i <= 1000000; i ++ )
    		wp[i] = (i - 1) * ((wp[i - 1] % mod) + (wp[i - 2] % mod)) % mod;
    	pw[1] = 1;
    	for (ll i = 2; i <= 1000001; i ++ )
    		pw[i] = pw[i - 1] * i % mod;
    	inv[1000001] = qpow(pw[1000001], mod - 2);
    	for (ll i = 1000000; i >= 0; i -- )
    		inv[i] = inv[i + 1] * (i + 1) % mod;
    	while (t -- )
    	{
    		n = read(); m = read();
    		printf("%lld
    ", (((pw[n] * inv[m]) % mod) * inv[n - m] % mod) * wp[n - m] % mod);
    	}
    	return 0;
    }
    
  • 相关阅读:
    MDK+VS+Eclipse的STM32库V3.5工程模板的建立(六)
    MDK+VS+Eclipse的STM32库V3.5工程模板的建立(一)
    MDK+VS+Eclipse的STM32库V3.5工程模板的建立(四)
    ognl.OgnlException: target is null for setProperty(null, "username", [Ljava.lang.String;@19af9e98)
    Hibernate联合主键Annotation
    struts2入门第一天配置环境
    为什么java的构造方法中this()或者super()要放在第一行
    几种解决IE6下PNG图片透明问题
    IE6解决min_height
    一个拖拽例子
  • 原文地址:https://www.cnblogs.com/andysj/p/13966159.html
Copyright © 2011-2022 走看看