bzoj4517 [Sdoi2016]排列计数

Description

求有多少种长度为 n 的序列 A,满足以下条件:
1 ~ n 这 n 个数在序列中各出现了一次
若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的
满足条件的序列可能很多,序列数对 10^9+7 取模。

Input

第一行一个数 T,表示有 T 组数据。
接下来 T 行,每行两个整数 n、m。
T=500000,n≤1000000,m≤1000000

Output

输出 T 行,每行一个数,表示求出的序列数

Sample Input

5
1 0
1 1
5 2
100 50
10000 5000

Sample Output

0
1
20
578028887
60695423
 
正解:组合数学。
这题要用到错排公式,虽然做这题之前我不知道这是什么,不过最后我还是自己欧出来了。。
首先,我们容易得到,答案就是$\binom{n}{m}$乘上错排公式(即$i$不在第$i$个位置上的数的方案数)。
然后这个错排随便欧一下就出来了啊。。
用二项式反演证明,可得:$g(n)=\sum_{k=0}^{n}(-1)^{n-k}\binom{n}{k}f(k)$
然后预处理出来,就没了。
 
 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <complex>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <cstdio>
 8 #include <vector>
 9 #include <cmath>
10 #include <queue>
11 #include <stack>
12 #include <map>
13 #include <set>
14 #define rhl (1000000007)
15 #define inf (1<<30)
16 #define N (1000010)
17 #define il inline
18 #define RG register
19 #define ll long long
20 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
21 
22 using namespace std;
23 
24 ll fac[N],f[N],g[N];
25 int n,m;
26 
27 il int gi(){
28     RG int x=0,q=1; RG char ch=getchar();
29     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
30     if (ch=='-') q=-1,ch=getchar();
31     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
32     return q*x;
33 }
34 
35 il void pre(){
36     fac[0]=fac[1]=f[1]=g[1]=g[2]=1,fac[2]=f[2]=2;
37     for (RG int i=3;i<N;++i){
38     fac[i]=fac[i-1]*i%rhl;
39     g[i]=(g[i-1]*i%rhl-f[i-3]+rhl)%rhl;
40     f[i]=g[i]*i%rhl;
41     }
42     return;
43 }
44 
45 il ll qpow(RG ll a,RG ll b){
46     RG ll ans=1;
47     while (b){
48     if (b&1) ans=ans*a%rhl;
49     a=a*a%rhl,b>>=1;
50     }
51     return ans;
52 }
53 
54 il ll cm(RG int n,RG int m){
55     return fac[n]*qpow(fac[m],rhl-2)%rhl*qpow(fac[n-m],rhl-2)%rhl;
56 }
57 
58 int main(){
59     File("sequence");
60     RG int T=gi(); pre();
61     while (T--){
62     n=gi(),m=gi(); if (n==m){ puts("1"); continue; }
63     printf("%lld\n",cm(n,m)*f[n-m-1]%rhl);
64     }
65     return 0;
66 }

 

posted @ 2017-04-11 14:58  wfj_2048  阅读(230)  评论(0编辑  收藏  举报