今年sdoi一改風格全是傻逼題,居然變成了今天的T2
答案顯然是Cn,m*f【n-m】,f表示錯排的答案。
顯然我們需要計算逆元,錯排,和階乘
都預處理出來就艹過去了
然而考試的時候傻逼寫了cout,T成60暴力分,直接rank10去了
/* ***********************************************
Author :BPM136
Created Time :2016-4-25 8:33:15
File Name :B.cpp
************************************************ */
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<bitset>
#include<queue>
#include<ctime>
#include<set>
#include<utility>
#include<vector>
#include<functional>
#include<numeric>
#include<memory>
#include<iterator>
#define LL long long
#define DB double
#define LB long double
#define UL unsigned long
#define ULL unsigned long long
#define pb push_back
#define popb pop_back
#define get(a,i) a&(1<<(i-1))
#define PAU putchar(32)
#define ENT putchar(10)
#define clr(a,b) memset(a,b,sizeof(a))
#define fo(_i,_a,_b) for(int _i=_a;_i<=_b;_i++)
#define fd(_i,_a,_b) for(int _i=_a;_i>=_b;_i--)
#define efo(_i,_a) for(int _i=last[_a];_i!=0;_i=e[_i].next)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
#define mkd(x) freopen(#x".in","w",stdout);
#define setlargestack(x) int size=x<<20;char *p=(char*)malloc(size)+size;__asm__("movl %0, %%esp\n" :: "r"(p));
#define end system("pause")
using namespace std;
LL read()
{
LL f=1,d=0;char s=getchar();
while (s<48||s>57){if (s==45) f=-1;s=getchar();}
while (s>=48&&s<=57){d=d*10+s-48;s=getchar();}
return f*d;
}
LL readln()
{
LL f=1,d=0;char s=getchar();
while (s<48||s>57){if (s==45) f=-1;s=getchar();}
while (s>=48&&s<=57){d=d*10+s-48;s=getchar();}
while (s!=10) s=getchar();
return f*d;
}
inline void write(LL x)
{
if(x==0){putchar(48);return;}if(x<0)putchar(45),x=-x;
int len=0,buf[20];while(x)buf[len++]=x%10,x/=10;
for(int i=len-1;i>=0;i--)putchar(buf[i]+48);return;
}
inline void writeln(LL x){write(x);ENT;}
const int N = 1000005;
const int M = 1000005;
const int MOD = 1000000007;
LL f[N];
LL n,m;
LL inv[N];
LL fac[N];
void prework() {
f[0] = 1; f[1] = 0; f[2] = 1;
fo(i, 3, N-5) {
f[i] = (LL)(i - 1) * ((f[i - 1] + f[i - 2]) % MOD) % MOD;
}
inv[1] = 1;
fo(i, 2, N-5)
inv[i] = (MOD - MOD / i) * inv[ MOD % i ] % MOD;
fac[0] = fac[1] = 1;
fo(i, 2, N-5)
fac[i] = (LL)fac[i - 1] * i %MOD;
}
LL KSM(LL a, LL k) {
LL ret = 1;
while (k) {
if(k & 1) ret = ret * a %MOD;
a = a * a %MOD;
k >>= 1;
}
return ret;
}
/*
LL C(int n, int m) {
if (m == 0) return 1;
int nm = n - m;
int be = max(nm, m);
int en = min(nm, m);
LL ret = n --;
fo(i , 2, en) {
ret = (LL) ret * n %MOD * inv[i] % MOD;
n --;
}
return ret;
}
*/
struct nodet {
LL x,y;
};
nodet EXgcd(LL a, LL b) {
if(b == 0) {
nodet ret ;
ret.x = 1;
ret.y = 0;
return ret;
}
nodet tmp = EXgcd(b, a % b);
nodet ret;
ret.x = tmp.y;
ret.y = tmp.x - (a / b) * tmp.y;
return ret;
}
LL ny(int x) {
nodet tmp = EXgcd(x, MOD);
LL ret = (tmp.x %MOD + MOD) %MOD;;
return ret;
}
LL C(int n, int m) {
LL k = (LL) fac[n - m] * fac[m] %MOD;
if(k < 1000000) return (LL) fac[n] * inv[k] %MOD;
return (LL) fac[n] * ny( k ) %MOD;
}
void init() {
n=read(), m=read();
}
void work() {
if(n < m) puts("0");
else {
printf("%lld\n",(LL)C(n, m) %MOD * f[n - m] % MOD);
}
}
int main() {
file(permutation);
prework();
int T = read();
while(T--) {
init();
work();
}
return 0;
}