G. The Galactic Olympics(2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest (ECPC 16)题解)
题目链接:G. The Galactic Olympics
思路:第二类斯特林数,可以用\(dp\)预处理,也可以根据通项公式求解;
通项公式:\(\begin{Bmatrix} n\\k \end{Bmatrix}= \sum_{i=0}^{k}\frac{{-1}^{k-i} i^n}{i!(k-i)!}\)
然后记住一点对于负数的取模是 ((k%mod)+mod)%mod
\(Code1:\)
#include<set>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define rep(i,a,b) for(auto i=a;i<=b;++i)
#define bep(i,a,b) for(auto i=a;i>=b;--i)
#define lowbit(x) (x&(-x))
#define ch() getchar()
#define pc(x) putchar(x)
using namespace std;
template<typename T>void read(T&x){
static char c;static int f;
for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
}
template<typename T>void write(T x){
static char q[65];int cnt=0;
if(x<0)pc('-'),x=-x;
q[++cnt]=x%10,x/=10;
while(x)
q[++cnt]=x%10,x/=10;
while(cnt)pc(q[cnt--]+'0');
}
const int N = 1e3+10;
const ll mod = 1e9+7;
int t,d[N],n,f[N];bool st[N],vis[N];
int q[N];
ll inv(ll a){
if(a == 1)return 1;
return inv(mod%a)*(mod - mod/a)%mod;
}
ll p[N],up[N];
ll pows[N][N];
void solve(){
//1000 999
freopen("galactic.in","r",stdin);
read(t);
p[0] = 1;up[0] = 1;
rep(i,1ll,1000ll){p[i] = (p[i-1]%mod * i%mod)%mod;up[i] =inv(p[i])%mod;}
rep(i,1,1000){
pows[i][0] = 1;
rep(j,1,1000)pows[i][j] = (pows[i][j-1]*i)%mod;
}
while(t--){
int n,k;
read(n);read(k);
if(n < k)puts("0");
else if(n>k){
ll sum = 0;
rep(i,0,k){
ll now = (up[i]%mod*up[k-i]%mod)%mod;
ll b = pows[i][n]%mod;
ll c =(b%mod*(now%mod))%mod;
if((k-i)%2)c=-c;
c=((c%mod)+mod)%mod;
sum += c;
sum %= mod;
}
//sum = abs(sum);
sum %=mod;
ll ans = sum * p[k]%mod;
ans %= mod;
write(ans);pc('\n');
}
else {
write(p[n]%mod);pc('\n');
}
}
}
signed main(){solve(); return 0; }
\(Code2:\)
#include<set>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define rep(i,a,b) for(auto i=a;i<=b;++i)
#define bep(i,a,b) for(auto i=a;i>=b;--i)
#define lowbit(x) (x&(-x))
#define ch() getchar()
#define pc(x) putchar(x)
using namespace std;
template<typename T>void read(T&x){
static char c;static int f;
for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
}
template<typename T>void write(T x){
static char q[65];int cnt=0;
if(x<0)pc('-'),x=-x;
q[++cnt]=x%10,x/=10;
while(x)
q[++cnt]=x%10,x/=10;
while(cnt)pc(q[cnt--]+'0');
}
const int N = 1e3+10;
const ll mod = 1e9+7;
int t;ll f[N][N],p[N];
void solve(){
//1000 999
freopen("galactic.in","r",stdin);
f[0][0] = 1;
rep(i,1,1000){
rep(j,1,i){
f[i][j] = (f[i-1][j-1] + j * f[i-1][j])%mod;
}
}p[0] = 1;
rep(i,1,1000){
p[i] = (p[i-1]*i)%mod;
}
read(t);
while(t--){
int n,k;
read(n);read(k);
if(n < k)puts("0");
else if(n>k){
ll ans = f[n][k];
ans *= p[k];
ans %=mod;
write(ans);pc('\n');
}
else {
write(p[n]%mod);pc('\n');
}
}
}
signed main(){solve(); return 0; }