题目链接
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;
}