1. 程式人生 > 遊戲 >Fami通新一週銷量榜 《寶可夢晶燦鑽石/明亮珍珠》二連冠

Fami通新一週銷量榜 《寶可夢晶燦鑽石/明亮珍珠》二連冠

https://www.luogu.com.cn/problem/CF997C

\(f(i,j)\)表示的是欽定\(i\)\(j\)列相同的方案數

大力推式子即可

code:

#include<bits/stdc++.h>
#define ll long long
#define N 2000050
#define mod 998244353
using namespace std;
ll qpow(ll x, ll y) { 
    if(y < 0) return qpow(qpow(x, -y), mod - 2);
    x = (x % mod + mod) % mod, y %= mod - 1;
    ll ret = 1;
    for(; y; y >>= 1, x = x * x % mod) if(y & 1) ret = ret * x % mod;
    return ret;
}
ll fac[N], ifac[N];
void init(int n) {
    fac[0] = 1;
    for(int i = 1; i <= n; i ++) fac[i] = fac[i - 1] * i % mod;
    ifac[n] = qpow(fac[n], mod - 2);
    for(int i = n - 1; i >= 0; i --) ifac[i] = ifac[i + 1] * (i + 1) % mod;
}
ll C(int n, int m) {
    return fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}
ll n;
int main() {
    scanf("%lld", &n);
    init(n);

    ll ans = 0;
    for(int i = 1; i <= n; i ++) (ans += 2ll * C(n, i) % mod * qpow(-1, i + 1) % mod * qpow(3, i) % mod * qpow(3, n * (n - i)) % mod) %= mod;
    
   // printf("%lld\n", ans);

    ll t = (mod - 1) * qpow(3, n * n + 1) % mod;
    for(int i = 1; i <= n; i ++) {
        ll o = C(n, i) * qpow(3, -i * n) % mod * qpow(-1, i) % mod;
        o = o * (qpow(1 - qpow(3, i - n), n) - 1 + mod) % mod;
        //printf("%lld %lld  %lld\n", ans, o * t % mod, (ans + o * t % mod) % mod);
        (ans += o * t % mod) %= mod;
        
    //    printf("%lld %lld   %lld\n", o * t % mod, t, (qpow(1 - qpow(3, i - n), n) - 1 + mod) % mod);
    }
    printf("%lld", ans);
    return 0;
}