http://www.lydsy.com/JudgeOnline/problem.php?id=4517
题意十分的明显
写了半天一不小心F5刷新了GG
明显的组合数加错排数
错排数的话可以线性的dp出来
for (int i=2;i<=1000000;i++){
f[i]=f[i-1]*i%M;
if (i&1) f[i]--;
else f[i]++;
}
组合数的话用lucas定理来算
这道题千万别在n,m使用cin
否则会RUNTIME_ERROR
别问我为什么
我也不知道
浪费了我半个小时的时间
GG
啦啦啦
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e9+7,N=1e6;
ll Jc[N+10],f[N+10];
ll quickmod(ll a,ll b,ll m){ll ans=1;while(b)
{if(b&1)ans=(ans*a)%m;b>>=1;a=a*a%m;}return ans;}
ll inv(ll a,ll p){return quickmod(a, p-2, p);}
ll C(ll a,ll b,ll m){ //计算C(a, b)
return Jc[a]*inv(Jc[b],m)%m
*inv(Jc[a-b],m)%m;
}
int main(){
Jc[0]=1;
for (int i=1;i<=1000000;i++) Jc[i]=Jc[i-1]*i%M;
f[0]=1;
for (int i=2;i<=1000000;i++){
f[i]=f[i-1]*i%M;
if (i&1) f[i]--;
else f[i]++;
}
int T;
cin>>T;
int n,m;
while(T--){
scanf("%d%d",&n,&m);
printf("%d\n",C(n,m,M)*f[n-m]%M);
}
}