题解 [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;
}