题目概述
如果
ai=i
则
i
是稳定的。给出
解题报告
其实很简单……先选出
m
个稳定位置,然后另外
强制不稳定也就是 ai≠i ,即错排。
错排递推公式:
D(0)=1,D(1)=0,D(i)=(i−1)[D(i−2)+D(i−1)]
。
推导:将
i
放在
然后若
k
在
否则就当
k
是
示例程序
#include<cstdio>
#include<cctype>
using namespace std;
typedef long long LL;
const int maxn=1000000,MOD=1e9+7;
int te,n,m,fac[maxn+5],INV[maxn+5],D[maxn+5];
#define Eoln(x) ((x)==10||(x)==13||(x)==EOF)
inline char readc()
{
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF;return *l++;
}
inline int readi(int &x)
{
int tot=0,f=1;char ch=readc(),lst='+';
while (!isdigit(ch)) {if (ch==EOF) return EOF;lst=ch;ch=readc();}
if (lst=='-') f=-f;
while (isdigit(ch)) tot=(tot<<3)+(tot<<1)+ch-48,ch=readc();
return x=tot*f,Eoln(ch);
}
void Make()
{
INV[0]=INV[1]=1;for (int i=2;i<=maxn;i++) INV[i]=MOD-(LL)(MOD/i)*INV[MOD%i]%MOD;
fac[0]=fac[1]=1;for (int i=2;i<=maxn;i++) fac[i]=(LL)fac[i-1]*i%MOD,INV[i]=(LL)INV[i-1]*INV[i]%MOD;
D[0]=1;D[1]=0;for (int i=2;i<=maxn;i++) D[i]=(LL)(i-1)*(D[i-1]+D[i-2])%MOD;
}
inline int C(int x,int y) {if (x<y) return 0;return (LL)fac[x]*INV[y]%MOD*INV[x-y]%MOD;}
int main()
{
freopen("program.in","r",stdin);
freopen("program.out","w",stdout);
for (Make(),readi(te);te;te--)
{
readi(n);readi(m);if (n<m) {puts("0");continue;}
printf("%lld\n",(LL)C(n,m)*D[n-m]%MOD);
}
return 0;
}