CF 997C Sky Full of Stars

有一个 n × n ( n ≤ 1 0 6 ) n \times n ( n \leq 10^6 ) n×n(n106)的正方形网格,用红色,绿色,蓝色三种颜色染色,求有多少种染色方案使得至少一行或一列是同一种颜色。结果对 998244353 998244353 998244353 取模。

sol:

可以二维容斥,得到
∑ i = 0 n ∑ j = 0 n C n i C n j ( − 1 ) i + j ( ( ! i ∣ ∣ ! j ) ? 3 i + j : 3 ) 3 ( n − j ) ( n − i ) \sum_{i=0}^n\sum_{j=0}^n{C_n^iC_n^j(-1)^{i+j}((!i||!j)?3^{i+j}:3)3^{(n-j)(n-i)}} i=0nj=0nCniCnj(1)i+j((!i!j)?3i+j:3)3(nj)(ni)

发现后边的指数 3 ( n − i ) ( n − j ) 3^{(n-i)(n-j)} 3(ni)(nj)可以变成 ( 3 n − i ) n − j (3^{n-i})^{n-j} (3ni)nj然后二项式定理

复杂度 n l o g n nlogn nlogn

#include
#include
typedef long long LL;
const LL p = 998244353;
const int N = 1e6+7;
inline LL FST(LL b, LL k) {
  LL ans = 1;b %= p;
  while (k) {
    if (k & 1) ans = ans * b % p; b = b * b % p; k >>= 1;
  } return ans;
}
LL ifac[N], fac[N], inv[N];
const int lim = 1e6;
void init() {
  inv[0] = inv[1] = fac[1] = fac[0] = 1;
  for (int i = 2; i <= lim; i++)
    inv[i] = (p - p / i) * inv[p % i] % p;
  for (int i = 2; i <= lim; i++)
    fac[i] = (fac[i - 1] * i) % p,
    inv[i] = inv[i - 1] * inv[i] % p;
}
inline LL C(LL a, LL b) {
  return (fac[a] * inv[a - b]) % p * inv[b] % p;
}
LL n, m;
int main() {
  init();scanf("%lld", &n);LL ans = FST(3, n * n); LL ret = 0;
  for (int i = 1; i <= n; i++) {
    LL res = C(n, i) * FST(-1, i) % p * (FST(FST(3, n - i) - 1, n) % p - FST(3, (n * (n - i)))) % p * 3LL % p;
    ret = ((ret + res) % p + p) % p;
  }
  for (int i = 0; i <= n; i++) {
    LL res = C(n, i) * FST(-1, i) % p * FST(3, n * (LL)(n - i) + i) % p * 2LL % p;
    ret = ((ret + res) % p + p) % p;
  } ret = ((ret - FST(3, n * n)) % p + p) % p;
  ans = ((ans - ret) % p + p) % p;
  printf ("%lld", (ans % p + p) % p);
}

你可能感兴趣的:(容斥原理,数数)