BZOJ 4517 排列计数

Posted on 2016-09-18 16:10  ziliuziliu  阅读(114)  评论(0编辑  收藏  举报

23333333333式子方向推错了。。。。

错排公式,记住就好。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000500
#define mod 1000000007
using namespace std;
long long t,n,m,f[maxn],table[maxn];
long long read()
{
    long long data=0;char ch;
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9')
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data;
}
void get_table()
{
    f[0]=1;f[1]=0;f[2]=1;
    for (long long i=3;i<=maxn-500;i++)
        f[i]=(i-1)*((f[i-1]+f[i-2])%mod)%mod;
    table[0]=table[1]=1;
    for (long long i=2;i<=maxn-500;i++)
        table[i]=table[i-1]*i%mod;
}
long long f_pow(long long a,long long b)
{
    long long ans=1,base=a;
    while (b)
    {
        if (b&1) ans=ans*base%mod;
        base=base*base%mod;
        b>>=1;
    }
    return ans;
}
long long inv(long long x)
{
    return f_pow(x,mod-2);
}
void work()
{
    n=read();m=read();
    printf("%lld\n",((table[n]*inv(table[m]))%mod*inv(table[n-m]))%mod*f[n-m]%mod);
}
int main()
{
    t=read();
    get_table();
    for (long long i=1;i<=t;i++)
        work();
    return 0;
}