codeforces 997-C. Sky Full of Stars


题目链接

https://codeforces.com/contest/997/problem/C

题意

给一个n*n的矩阵,要往每个格子涂rgb三种颜色之一。问有多少种涂色方案,满足至少有一列或者一行的颜色是相同的。

分析

ans=至少有一行的+至少有一列的-至少有一行且有一列的
\[ ans=2\sum_{i=1}^{n} (-1)^{i+1} C^i_n \times 3^{(n-i)n}\times3^i -\sum_{i=1}^{n}\sum_{j=1}^{n}(-1)^{i+j}3 C_n^i C_n^j3^{(n-i)(n-j)} \]

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1000050;
ll fact[maxn],inv[maxn];
const ll MOD=998244353;
ll Pow(ll x,ll n){
    ll ans=1,base=x%MOD;
    while(n){
        if(n&1) ans=ans*base%MOD;
        base=base*base%MOD;
        n>>=1;
    }
    return ans;
}
void init(){
    fact[0]=1;
    for(int i = 1; i < maxn; ++i)
        fact[i]=fact[i-1]*i%MOD;
    inv[maxn-1]=Pow(fact[maxn-1],MOD-2);
    for(int i = maxn-2; i >= 0; --i)
        inv[i]=inv[i+1]*(i+1)%MOD;
}
int main(){
    init();
    int n;
    cin>>n;
    ll ans=0;
    for(int i = 1; i <= n; ++i){
        ll t=fact[n]*inv[i]%MOD*inv[n-i]%MOD*Pow(3,(ll)n*(n-i)+i)%MOD;
        if(i%2==0) t=-t;
        ans=(ans+t)%MOD;
        if(ans>=MOD) ans-=MOD;
        else if(ans<0) ans+=MOD;
    }
    ans=ans*2%MOD;
    ll p=1;
    for(int i = 0; i < n; ++i){
        ll t=fact[n]*inv[i]%MOD*inv[n-i]%MOD*3%MOD*(Pow(1-p,n)-Pow(-p,n))%MOD;
        if(i%2==0) t=-t;
        p=p*3%MOD;
        ans=(ans+t)%MOD;
        if(ans>=MOD) ans-=MOD;
        else if(ans<0) ans+=MOD;
    }
    cout<<(ans%MOD+MOD)%MOD<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sciorz/p/9254774.html