codeforces997C Sky full of stars

传送门:http://codeforces.com/problemset/problem/997/C

【题解】

注意在把$i=0$或$j=0$分开考虑的时候,3上面的指数应该是$n(n-j)+j$

至少一行一列相同颜色,那么这些相同颜色的行列一定是同一种颜色,所以是$3^((n-i)(n-j)+1)$。

如果只有若干行相同颜色,那么这些相同颜色的行之间的颜色不一定相同,所以是$3^((n-j)j+j)$。

# include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int mod = 998244353;
const int M = 1e6 + 10;

int n, fac[M], inv[M];

inline int pwr(int a, int b) {
    int ret = 1;
    while(b) {
        if(b&1) ret = 1ll * ret * a % mod;
        a = 1ll * a * a % mod;
        b >>= 1;
    }
    return ret;
}

inline int C(int n, int m) {
    return 1ll * fac[n] * inv[m] % mod * inv[n-m] % mod;
}


int main() {
    cin >> n;
    fac[0] = 1; inv[0] = 1;
    for (int i=1; i<=n; ++i) fac[i] = 1ll * fac[i-1] * i % mod;
    inv[n] = pwr(fac[n], mod-2);
    for (int i=n-1; i>=1; --i) inv[i] = 1ll * inv[i+1] * (i+1) % mod;
    int A = 0, B = 0;    
    for (int j=1; j<=n; ++j) {
        int tem = 1ll * C(n, j) * pwr(3, (1ll * n * (n-j) + j) % (mod-1)) % mod;
        if(j&1) B += tem;
        else B -= tem;
        if(B >= mod) B -= mod;
        if(B < 0) B += mod;
    }
    B <<= 1;
    if(B >= mod) B -= mod; 
    
    int q = 1;
    for (int i=0; i<n; ++i) {
        int t = pwr(-q+mod+1, n) - pwr(-q+mod, n);
        if(t < 0) t += mod;
        if(i&1) A = A + 1ll * C(n, i) * t % mod;
        else A = A - 1ll * C(n, i) * t % mod;
        if(A >= mod) A -= mod;
        if(A < 0) A += mod;
        q = 3ll * q % mod; 
    }
    A = 3ll * A % mod;
    int ans = A+B;
    if(ans >= mod) ans -= mod;
    cout << ans;
        
    return 0;
}
View Code

 

posted @ 2019-02-10 15:42  Galaxies  阅读(277)  评论(0编辑  收藏  举报