# 【BZOJ 4517】【SDOI 2016 Round1 Day2 T2】排列计数

PS:在BZOJ上凑个热闹233

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int p = 1E9 + 7;
int getint() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = k * 10 + c - '0';
return k * fh;
}
long long f[1000003], ni[1000003], nic[1000003], jc[1000003];
void mktb(int n) {
f[0] = 1;
f[1] = 0;
f[2] = 1;
for(int i = 3; i <= n; ++i)
f[i] = (((f[i - 1] + f[i - 2])%p) * (i - 1)) % p;
jc[1] = 1;
for(int i = 2; i <= n; ++i)
jc[i] = (jc[i - 1] * i) % p;
}
void exgcd(int a, int b, long long &x, long long &y) {
if (b == 0) {
x = 1; y = 0;
} else {
exgcd(b, a % b, x, y);
long long t = x;
x = y;
y = t - a / b * y;
}
}
void mkny(int n) {
long long x, y;
ni[1] = 1;
for(int i = 2; i <= n; ++i) {
exgcd(i, p, x, y);
ni[i] = x < 0 ? x + p : x;
}
nic[0] = 1;
nic[1] = 1;
for(int i = 2; i <= n; ++i)
nic[i] = (nic[i - 1] * ni[i]) % p;
}

struct node {
int n, m;
} q[500003];
int upe = 0;

long long Q(int n, int m) {
if (n < m) return 0;
long long ans = (jc[n] * nic[m]) % p;
ans = (ans * nic[n - m]) % p;
ans = (ans * f[n - m]) % p;
return ans;
}
int main() {
freopen("permutation.in", "r", stdin);
freopen("permutation.out", "w", stdout);
for(int i = 1; i <= T; ++i) {
if (q[i].n > upe)
upe = q[i].n;
}
mktb(upe);
mkny(upe);
for(int i = 1; i <= T; ++i)
printf("%I64d\n", Q(q[i].n, q[i].m));
fclose(stdin);
fclose(stdout);
return 0;
}


NOI 2017 Bless All
posted @ 2016-04-11 19:06  abclzr  阅读(356)  评论(0编辑  收藏  举报