【题解】Gym101933K King's Colors题解

\(\text{King's Colors}\)\({}^\texttt{Gym 101933K}\)题解

定义:\(f_i\) 表示使用了至多 \(i\) 种颜色的方案数;\(g_i\) 表示使用了恰好 \(i\) 种颜色的方案数。

那么 \(f_i=\displaystyle{ {m\choose i}\cdot \sum{i\choose j}\cdot g_j}\)\(f_i=\displaystyle {m\choose i}(i-1)^{n-1}i\)

\(h_i=\displaystyle{\frac{f_i}{\displaystyle{m\choose i}}}=(i-1)^{n-1}i\)\(\therefore h_i=\displaystyle{ \sum{i\choose j}\cdot g_j}\)

令矩阵 \(A_{i,j}=\displaystyle {i\choose j}\),则 \(A^{-1}_{i,j}=\displaystyle {i\choose j}\times (-1)^{i-j}\)

\(\because h=Ag \\\therefore g=A^{-1}h\\\therefore g_i=A_{i,j}^{-1}\times h_j=\displaystyle{i\choose j}\times (-1)^{i-j}\times (j-1)^{n-1}\times j\\\therefore g_{m}=\displaystyle{m\choose j}\times (-1)^{m-j}\times (j-1)^{n-1}\times j\)

Code

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
//#define int long long
namespace gtx{
//	Fast IO
    void read(int &x){
        x = 0;int h = 1;char tmp;
        do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp));
        while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar();
        x*=h;
    }
    void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');}
    void write(char x){putchar(x);}
    void write(int x){
        if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0;
        do st[++tot]=x%10,x/=10; while(x);
        while(tot){putchar(st[tot--]+'0');}
    }
    void write(int x,char y){write(x);write(y);}
#ifndef int
    void read(long long &x){
        x = 0;int h = 1;char tmp;
        do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp));
        while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar();
        x*=h;
    }
    void write(long long x){
        if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0;
        do st[++tot]=x%10,x/=10; while(x);
        while(tot){putchar(st[tot--]+'0');}
    }
    void write(long long x,char y){write(x);write(y);}
#endif
    const int MAXN = 2'500+10;
    const int MOD = 1e9+7;
    int n,m;
    int qpow(int x,int y){
        if(y<0) return qpow(qpow(x,-y),MOD-2);
        long long now = x;
        long long ans = 1;
        while(y){
            if(y&1){
                ans *= now;ans%=MOD;
            }
            now *= now; now%=MOD;
            y>>=1;
        }
        return ans;
    }
    int frac[MAXN],invfrac[MAXN];
    int inv(int x){
        return qpow(x,MOD-2);
    }
    int C(int n,int m){
        return 1ll*frac[n]*invfrac[m]%MOD*invfrac[n-m]%MOD;
    }
    signed main(){
        read(n);read(m);
        frac[0] = invfrac[0] = 1;
        for(int i = 1;i<=n;i++){
            frac[i] = 1ll*frac[i-1]*i%MOD;
            invfrac[i] = inv(frac[i]);
        }
        int ans = 0;
        for(int j = 2;j<=m;j++){
            ans += 1ll*C(m,j)*((m-j)&1?-1:1)%MOD*qpow(j-1,n-1)%MOD*j%MOD;
            ans %= MOD;
        }
        write((ans%MOD+MOD)%MOD);
        return 0;
    }
}
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
//	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int T = 1;
//	gtx::read(T);
    while(T--) gtx::main();
    return 0;
}
posted @ 2025-05-01 16:02  GuTongXing  阅读(9)  评论(0)    收藏  举报