SDOI2016 R1 day2 T2 排列計數 數論

今年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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章