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

posted @ 2021-05-12 09:42  xiaodangao  阅读(50)  评论(0编辑  收藏  举报