SDOI2016 R1 day2 T2 排列计数 数论

来源:互联网 发布:java break用法 编辑:程序博客网 时间:2024/06/05 05:24

今年sdoi一改风格全是傻逼题,居然变成了今天的T2

答案显然是Cn,m*f【n-m】,f表示错排的答案。

显然我们需要计算逆元,错排,和阶乘

都预处理出来就艹过去了

然而考试的时候傻逼写了cout,T成60暴力分,直接rank10去了

/* ***********************************************Author        :BPM136Created Time  :2016-4-25 8:33:15File 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;}


0 0