cf 493 div.1 C

题意:

给出n*n的矩阵,用三种颜色染色,保证至少有一行或一列颜色全部相同


题解

容斥,推式子,把只选行或列单列出来

详见:点击打开链接

根据式子来写就好了,注意细节

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

typedef long long ll;
const ll p = 998244353;
ll fac[maxn],inv[maxn],pow_[maxn],ans;
int n;

inline ll pow_er(ll x,int y){
	ll res = 1;
	while ( y ) {
		if ( y & 1 ) res = res * x % p;
		x = x * x % p;
		y >>= 1;
	}
	return res;
}
void init(){
	fac[0] = 1 , pow_[0] = 1;
	for (int i = 1 ; i <= n ; i++){
		fac[i] = fac[i - 1] * i % p;
		pow_[i] = pow_[i - 1] * 3 % p;
	}
	inv[n] = pow_er(fac[n],p - 2);
	for (int i = n - 1 ; i >= 1 ; i--) inv[i] = inv[i + 1] * (i + 1) % p;
}
inline ll C(int n,int m){
	if ( n == m || !m ) return 1;
	return fac[n] * inv[m] % p * inv[n - m] % p;
}
void calc(){
//	if ( n == 1 ){ ans = 3; return; }
	for (int i = 1 ; i <= n ; i++){
	   if ( i & 1 )	ans = (ans + C(n,i) * pow_[i] % p * pow_er(pow_[n - i],n) * 2) % p;
	   else ans = ((ans - C(n,i) * pow_[i] % p * pow_er(pow_[n - i],n) * 2) % p + p) % p;
	}
	for (int i = 0 ; i < n ; i++){
		ll cur = 3ll * C(n,i) * (pow_er(1 - pow_[i],n) - pow_er(-pow_[i],n)) % p;
		if ( i & 1 ) ans = (ans + cur) % p;
		else ans = (ans - cur + p) % p;
	}
	ans = (ans % p + p) % p;
}
int main(){
	scanf("%d",&n);
	init();
	calc();
	cout<<ans<<endl;
	return 0;
}


猜你喜欢

转载自blog.csdn.net/weixin_42484877/article/details/80895656
今日推荐