[bzoj4517][Sdoi2016]排列计数
这题不就是个组合数加上错排公式吗?
数论稍稍学过一点的人都会啊.
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<iomanip> #include<algorithm> #include<map> using namespace std; #define LL long long #define FILE "dealing" #define up(i,j,n) for(int i=j;i<=n;++i) #define db double #define eps 1e-10 #define pii pair<int,int> int read(){ int x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f*x; } const int maxn=1000200,mod=(int)(1e9+7+0.1),limit=(int)(1e6+1); LL fac[maxn],inv[maxn],f[maxn]; LL C(int n,int m){ return fac[n]*inv[m]%mod*inv[n-m]%mod; } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); int T=read(); fac[0]=1; up(i,1,limit)fac[i]=fac[i-1]*i%mod; inv[0]=inv[1]=1; up(i,2,limit)inv[i]=(-mod/i)*inv[mod%i]%mod; up(i,1,limit)inv[i]=inv[i]*inv[i-1]%mod; f[0]=1,f[1]=0,f[2]=1; up(i,3,limit)f[i]=((LL)i-1)*((f[i-1]+f[i-2])%mod)%mod; while(T--){ int n=read(),m=read(); printf("%lld\n",(C(n,m)*f[n-m]%mod+mod)%mod); } return 0; }