题目链接
https://codeforces.com/contest/997/problem/C
题意
给一个n*n的矩阵,要往每个格子涂rgb三种颜色之一。问有多少种涂色方案,满足至少有一列或者一行的颜色是相同的。
分析
ans=至少有一行的+至少有一列的-至少有一行且有一列的
[ ans=2sum_{i=1}^{n} (-1)^{i+1} C^i_n imes 3^{(n-i)n} imes3^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;
}