习题:排列计数(错排&排列组合)
题目
思路
比较水的一道题
首先选出m个固定,接着将剩余的n-m个求错排就行了
$ ans=C_{n}^{m}*cp_{n-m} $
关于错排
代码
#include<iostream>
using namespace std;
#define int long long
const int mod=1e9+7;
int t;
int n,m;
int fac[1000005];
int inv[1000005];
int cp[1000005];
void read(int &x)
{
x=0;
char c=getchar();
int f=1;
while('0'>c||c>'9')
{
if(x=='-')
f=-1;
c=getchar();
}
while('0'<=c&&c<='9')
{
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
x*=f;
}
void write(int x)
{
if(x<10)
{
putchar(x+'0');
}
else
{
write(x/10);
putchar(x%10+'0');
}
}
void init()
{
fac[0]=fac[1]=1;
inv[0]=inv[1]=1;
for(int i=2;i<=1000000;i++)
fac[i]=fac[i-1]*i%mod;
for(int i=2;i<=1000000;i++)
inv[i]=inv[mod%i]*(mod-mod/i)%mod;
for(int i=2;i<=1000000;i++)
inv[i]=inv[i-1]*inv[i]%mod;
int s=-1;
int t=1;
cp[0]=1;
cp[1]=0;
for(int i=2;i<=1000000;i++)
{
cp[i]=((i-1)*(cp[i-1]+cp[i-2]))%mod;
while(cp[i]<0)
cp[i]+=mod;
}
}
int C(int n,int m)
{
return ((fac[n]*inv[n-m])%mod*inv[m])%mod;
}
signed main()
{
init();
read(t);
for(int i=1;i<=t;i++)
{
read(n);
read(m);
write(C(n,m)*cp[n-m]%mod);
putchar('\n');
}
return 0;
}

浙公网安备 33010602011771号