题解 [CF997C] Sky Full of Stars

传送门

不做评价

考虑计算没有任何一行一列同色的方案数
考虑枚举钦定有 \(i\)\(j\) 列同色
\(g_{i, j}\) 为有 \(i\)\(j\) 列同色方案数
\(i>0\and j>0\) 时有 \(g_{i, j}=\binom{n}{i}\binom{m}{j}3*3^{(n-i)(m-j)}\)
有一个为 0 时(以 j=0 为例)为 \(\binom{n}{i}3^i3^{n(n-i)}\)
然后讨论有没有为 0 的分别计算

难点在于均不为 0
需要计算这么个东西

\[3^{n^2+1}\sum\limits_{i=1}^n(-1)^i\binom{n}{i}3^{-in}\sum\limits_{j=1}^n(-1)^j\binom{n}{j}3^{-jn}3^{ij} \]

这个 \(3^{ij}\) 让前后的式子关联起来了,无法直接计算
然后一个神奇的东西:

  • 二项式反演的式子如果产生前后关联,且容斥内容不是函数的话有时是可以用二项式定理合并的
    举个例子:

    \[\sum\limits_{j=1}^n(-1)^j\binom{n}{j}3^{-jn}3^{ij} \]

    考虑将指数上的 \(j\) 孤立出来,构造一个 \(1^{n-j}\) 与之配对

    \[\begin{aligned}&=\sum\limits_{j=1}^n\binom{n}{j}1^{n-j}(-3^{i-n})^j\\&=(1-3^{i-n})^n-1 \end{aligned} \]

于是本题就做到了 \(O(n\log n)\)

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1000010
#define ll long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, k;
ll fac[N], inv[N], ans;
const ll mod=998244353, phi=mod-1;
inline ll C(int n, int k) {return fac[n]*inv[k]%mod*inv[n-k]%mod;}
inline ll qpow(ll a, ll b) {ll ans=1; for (; b; a=a*a%mod,b>>=1) if (b&1) ans=ans*a%mod; return ans;}

signed main()
{
	n=read();
	fac[0]=fac[1]=1; inv[0]=inv[1]=1;
	for (int i=2; i<=n; ++i) fac[i]=fac[i-1]*i%mod;
	for (int i=2; i<=n; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	for (int i=2; i<=n; ++i) inv[i]=inv[i-1]*inv[i]%mod;
	for (int i=1; i<=n; ++i) ans=(ans-(i&1?-2:2)*C(n, i)*qpow(3, i+1ll*(n-i)*n))%mod;
	for (int i=1; i<=n; ++i) ans=(ans-(i&1?-1:1)*C(n, i)*qpow(3, 1ll*n*n+1-1ll*i*n)%mod*(qpow(1-qpow(3, phi+i-n), n)-1))%mod;
	printf("%lld\n", (ans%mod+mod)%mod);

	return 0;
}
posted @ 2022-06-08 14:08  Administrator-09  阅读(35)  评论(0编辑  收藏  举报