【bzoj4517】 Sdoi2016—排列计数

http://www.lydsy.com/JudgeOnline/problem.php?id=4517 (题目链接)

题意

  求n个数中正好m个数位置不变的排列数。

Solution

  $${错排公式:D(n)=(n-1)*[D(n-1)+D(n-2)]}$$

  $${ans=D(n-m)*C(n,n-m)}$$

代码

// bzoj4517
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define MOD 1000000007
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

const int maxn=1000010;
LL D[maxn],fac[maxn];
int n,m;

LL power(LL a,LL b) {
	LL res=1;
	while (b) {
		if (b&1) res=res*a%MOD;
		b>>=1;a=a*a%MOD;
	}
	return res;
}
LL C(int n,int m) {
	return fac[n]*power(fac[m],MOD-2)%MOD*power(fac[n-m],MOD-2)%MOD;
}
int main() {
	int T;scanf("%d",&T);
	D[0]=1;D[1]=0;
	for (int i=2;i<=1000000;i++) D[i]=(i-1)*(D[i-2]+D[i-1])%MOD;
	fac[0]=1;fac[1]=1;
	for (int i=2;i<=1000000;i++) fac[i]=fac[i-1]*i%MOD;
	while (T--) {
		scanf("%d%d",&n,&m);
		printf("%lld\n",C(n,n-m)*D[n-m]%MOD);
	}
	return 0;
}

  

posted @ 2016-12-25 17:30  MashiroSky  阅读(321)  评论(1编辑  收藏  举报