• 传送门
  • 题目大意
  • 思路
  • 参考代码
  • 总结
传送门
题目大意

有一个 n×n(n≤106)n×n(n≤106)n \times n \pod {n \le 10^6} 的正方形网格。用三种颜色对每个格子染色,求有多少种染色方案使得至少一行或一列是同一种颜色。答案对 998244353998244353998244353 取模。

思路

正难则反,考虑求不存在一行或一列同色的方案数。结果反着也难……

正着做,考虑容斥。这里有行和列两个参数,如何容斥呢?我们定义 AiAiA_i 表示第 iii 行的颜色都相同的染色方案,用 Bi" role="presentation">BiBiB_i 表示第 jjj 行的颜色都相同的染色方案,那么我们要求的是:

|A1∪A2∪⋯∪An∪B1∪B2∪⋯∪Bn|" role="presentation">|A1∪A2∪⋯∪An∪B1∪B2∪⋯∪Bn||A1∪A2∪⋯∪An∪B1∪B2∪⋯∪Bn|

|A_1 \cup A_2 \cup \cdots \cup A_n \cup B_1 \cup B_2 \cup \cdots \cup B_n|
把上面这个式子具体地写出来,你就知道该如何容斥了:设至少有 iii 行的颜色一样,至少有 j" role="presentation">jjj 列的颜色一样,我们枚举 i+ji+ji + j 来容斥。这种具体写出并集式子的方法可以了解一下。

那么现在的问题是如何计算选了至少 iii 行和 j" role="presentation">jjj 列时的方案数。当 i=j=0i=j=0i = j = 0 时,显然为 3n23n23^{n^2};当 iii 和 j" role="presentation">jjj 其中之一为 000 时,先枚举是哪些行(或者列,下同),再枚举这些行是什么颜色,再枚举剩下的颜色,那么显然是 Cni⋅3i⋅3n(n−i)" role="presentation">Cin⋅3i⋅3n(n−i)Cni⋅3i⋅3n(n−i)\mathrm{C}_{n}^{i} \cdot 3^{i} \cdot 3^{n (n - i)};当 i,j>0i,j>0i, j > 0 时,注意到那些同色的行和列颜色都相同,因此答案为 CinCjn⋅3⋅3(n−i)(n−j)CniCnj⋅3⋅3(n−i)(n−j)\mathrm{C}_{n}^{i} \mathrm{C}_{n}^{j} \cdot 3 \cdot 3^{(n - i)(n - j)}。

不妨设:

f(i,j)=⎧⎩⎨⎪⎪3i⋅3n(n−i)3j⋅3n(n−j)3(n−i)(n−j)+1i=0j=0i,j>0f(i,j)={3i⋅3n(n−i)i=03j⋅3n(n−j)j=03(n−i)(n−j)+1i,j>0

f(i, j) = \begin{cases} 3^i \cdot 3^{n(n - i)} & i = 0 \\ 3^j \cdot 3^{n(n - j)} & j = 0 \\ 3^{(n - i)(n - j) + 1} & i, j > 0 \end{cases}
那么最终答案是:

∑i=0n∑j=min(1,i)nCinCjnf(i,j)(−1)i+j+1∑i=0n∑j=min(1,i)nCniCnjf(i,j)(−1)i+j+1

\sum_{i = 0}^{n} \sum_{j = \min(1, i)}^{n} \mathrm{C}_{n}^{i} \mathrm{C}_{n}^{j} f(i, j) (-1)^{i + j + 1}
注意上式 (−1)(−1)(-1) 的指数。于是我们立刻得到一个 O(n2)O(n2)O(n^2) 的做法。


我们不妨把 i=0i=0i = 0 或者 j=0j=0j = 0 的情况单独拿出来计算。由于总共只有 O(n)O(n)O(n) 项,因此这一步的时间复杂度为 O(n)O(n)O(n)。剩下的是:

∑i=1n∑j=1nCinCjn3(n−i)(n−j)+1(−1)i+j+1∑i=1n∑j=1nCniCnj3(n−i)(n−j)+1(−1)i+j+1

\sum_{i = 1}^{n} \sum_{j = 1}^{n} \mathrm{C}_{n}^{i} \mathrm{C}_{n}^{j} 3^{(n - i)(n - j) + 1} (-1)^{i + j + 1}


很自然想到按照 iii 和 j" role="presentation">jjj 分开,把只与 iii 有关的乘数移到外面去。在此之前,需要先把 (n−i)(n−j)" role="presentation">(n−i)(n−j)(n−i)(n−j)(n - i)(n - j) 拆开。

∑i=1n∑j=1nCinCjn3n2+1⋅3−in⋅3−jn⋅3ij⋅(−1)i⋅(−1)j⋅(−1)∑i=1n∑j=1nCniCnj3n2+1⋅3−in⋅3−jn⋅3ij⋅(−1)i⋅(−1)j⋅(−1)

\sum_{i = 1}^{n} \sum_{j = 1}^{n} \mathrm{C}_{n}^{i} \mathrm{C}_{n}^{j} 3^{n^2 + 1} \cdot 3^{-in} \cdot 3^{-jn} \cdot 3^{ij} \cdot (-1)^i \cdot (-1)^{j} \cdot (-1)
把能提出去的都提出去:

(−1)⋅3n2+1∑i=1nCin⋅3−in⋅(−1)i∑j=1nCjn⋅3−jn⋅(−1)j⋅3ij(−1)⋅3n2+1∑i=1nCni⋅3−in⋅(−1)i∑j=1nCnj⋅3−jn⋅(−1)j⋅3ij

(-1) \cdot 3^{n^2 + 1} \sum_{i = 1}^{n} \mathrm{C}_{n}^{i} \cdot 3^{-in} \cdot (-1)^{i} \sum_{j = 1}^{n} \mathrm{C}_{n}^{j} \cdot 3^{-jn} \cdot (-1)^j \cdot 3^{ij}
要是没有那个 3ij3ij3^{ij},这道题就做完啦!这个 3ij3ij3^{ij} 怎么解决呢?

观察右边的和式,整理一下得:

∑j=1nCjn⋅(−3−n+i)j∑j=1nCnj⋅(−3−n+i)j

\sum_{j = 1}^{n} \mathrm{C}_{n}^{j} \cdot (-3^{-n + i})^{j}
这这么像二项式定理,就直接套用二项式定理咯。只不过 j≠0j≠0j \ne 0,所以要减去 j=0j=0j = 0 的情况:

(1−3−n+i)n−1(1−3−n+i)n−1

(1 - 3^{-n + i})^n - 1
现在的答案是:

(−1)⋅3n2+1∑i=1nCin⋅3−in⋅(−1)i⋅((1−3−n+i)n−1)(−1)⋅3n2+1∑i=1nCni⋅3−in⋅(−1)i⋅((1−3−n+i)n−1)

(-1) \cdot 3^{n^2 + 1} \sum_{i = 1}^{n} \mathrm{C}_{n}^{i} \cdot 3^{-in} \cdot (-1)^{i} \cdot \left( (1 - 3^{-n + i})^n - 1 \right)
使用快速幂,时间复杂度 O(nlogn)O(nlog⁡n)O(n \log n)。

参考代码
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cctype>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <list>
#include <functional>
typedef long long LL;
typedef unsigned long long ULL;
using std::cin;
using std::cout;
using std::endl;
typedef int INT_PUT;
INT_PUT readIn()
{INT_PUT a = 0; bool positive = true;char ch = getchar();while (!(ch == '-' || std::isdigit(ch))) ch = getchar();if (ch == '-') { positive = false; ch = getchar(); }while (std::isdigit(ch)) { a = a * 10 - (ch - '0'); ch = getchar(); }return positive ? -a : a;
}
void printOut(INT_PUT x)
{char buffer[20]; int length = 0;if (x < 0) putchar('-'); else x = -x;do buffer[length++] = -(x % 10) + '0'; while (x /= 10);do putchar(buffer[--length]); while (length);
}const int mod = 998244353;
LL power(LL x, int y)
{LL ret = 1;while (y){if (y & 1) ret = ret * x % mod;x = x * x % mod;y >>= 1;}return ret;
}
const int inv3 = power(3, mod - 2);const int maxn = int(1e6) + 5;
int n;
int fac[maxn];
int invFac[maxn];
int power1[maxn];
int power2[maxn];
int invPower1[maxn];
int invPower2[maxn];
void init()
{fac[0] = 1;for (int i = 1; i <= n; i++)fac[i] = (LL)fac[i - 1] * i % mod;invFac[n] = power(fac[n], mod - 2) % mod;for (int i = n - 1; ~i; i--)invFac[i] = (LL)invFac[i + 1] * (i + 1) % mod;power1[0] = 1;for (int i = 1; i <= n; i++)power1[i] = (LL)power1[i - 1] * 3 % mod;power2[0] = 1;for (int i = 1; i <= n; i++)power2[i] = (LL)power2[i - 1] * power1[n] % mod;invPower1[0] = 1;for (int i = 1; i <= n; i++)invPower1[i] = (LL)invPower1[i - 1] * inv3 % mod;invPower2[0] = 1;for (int i = 1; i <= n; i++)invPower2[i] = (LL)invPower2[i - 1] * invPower1[n] % mod;
}
inline LL C(int down, int up)
{return down < up ? 0 : (LL)fac[down] * invFac[up] % mod * invFac[down - up] % mod;
}void run()
{n = readIn();init();LL ans = 0;for (int i = 1, sig = 1; i <= n; i++, sig = -sig)ans = (ans + (LL)C(n, i) * power1[i] % mod * power2[n - i] * sig) % mod;ans = (ans * 2) % mod;LL base = (LL)-power2[n] * 3 % mod;base = (base + mod) % mod;LL sum = 0;for (int i = 1, sig = -1; i <= n; i++, sig = -sig){sum = (sum + (LL)C(n, i) * invPower2[i] * sig % mod *(power(1 - invPower1[n - i], n) - 1)) % mod;}ans = (ans + base * sum) % mod;ans = (ans + mod) % mod;printOut(ans);
}int main()
{run();return 0;
}
总结

这道题本身不难,但还是看题解才做出来的,有几个原因:

  1. 出发点反了,没有想容斥,而是正难则反去了;
  2. 后面没有想到二项式定理。

也就是说这道题就是个容斥原理和二项式定理。二项式定理没什么好说的,注意它的结构。容斥原理可以把要算的内容具体的写出来,如果能写成并集形式就可以容斥了。

CF 997C Sky Full of Stars相关推荐

  1. [Codeforces 997C]Sky Full of Stars(排列组合+容斥原理)

    [Codeforces 997C]Sky Full of Stars(排列组合+容斥原理) 题面 用3种颜色对\(n×n\)的格子染色,问至少有一行或一列只有一种颜色的方案数.\((n≤10^6)\) ...

  2. CodeForces 997C Sky Full of Stars

    题目:点击打开链接 题意:给n*n个格子,每个格子可以填3种颜色.问有多少种填色方案,至少有一列或一行是同色的. 分析:首先反过来考虑,找不幸运的组合,因为这样便于容斥.  要把列和行分开考虑.  首 ...

  3. CodeForces - 997C Sky Full of Stars

    题面在这里! 题解见注释 /*设至少有i行,j列是一种颜色的方案数为 f(i,j)那么:1.i==0||j==0 时 , f(i,j) = C(n,i) * C(n,j) * 3^( (n-i)*(n ...

  4. 【CodeForces 997C】Sky Full of Stars(组合计数)

    题目链接:[CodeForces 997C]Sky Full of Stars 官方题解:Codeforces Round #493 - Editorial 题目大意:有一个n×nn×nn\times ...

  5. Codeforces 997 C - Sky Full of Stars

    C - Sky Full of Stars 思路: 容斥原理 题解:http://codeforces.com/blog/entry/60357 注意当i > 1 且 j > 1,是同一种 ...

  6. 数论五之容斥——硬币购物,Gerald and Giant Chess,幸运数字,Sky Full of Stars,已经没有什么好害怕的了

    容斥的神 [HAOI2008]硬币购物 problem solution code CF559C Gerald and Giant Chess problem solution code [SCOI2 ...

  7. cf997C. Sky Full of Stars(组合数 容斥)

    题意 题目链接 \(n \times n\)的网格,用三种颜色染色,问最后有一行/一列全都为同一种颜色的方案数 Sol Orz fjzzq 最后答案是这个 \[3^{n^2} - (3^n - 3)^ ...

  8. CF997C Sky Full of Stars

    CF997C , Luogu 有一个 \(n \times n ( n \leq 10^6)\)的正方形网格,用红色,绿色,蓝色三种颜色染色,求有多少种染色方案使得至少一行或一列是同一种颜色.结果对 ...

  9. CF997C Sky Full of Stars 数论

    正解:容斥 解题报告: 传送门! 两个方法,分别港下QAQ 先说第一种 首先要推出式子,就∑2*C(i,n)*(-1)i+1*3i*3n*n-n+3*∑∑(-1)i+j+1*C(i,n)*C(j,n) ...

最新文章

  1. qq分享组件 android,移动端,分享插件
  2. 中文分词最佳记录刷新了,两大模型分别解决中文分词及词性标注问题丨已开源...
  3. Tomcat - Tomcat套娃式架构与配置文件的对应关系解读
  4. classification、part segmentation、semantic segmentation、instance segmentation
  5. PHP定时抽奖怎么实现的,定时抽奖活动怎么做?
  6. hadoop学习路线2
  7. k3s 部署, 使用注意事项
  8. python——socket网络编程
  9. linux命令4--rmrmdir
  10. matlab炮灰模型,非诚勿扰的数学分析
  11. 【计算机基础】解决Win10电脑主机前面的耳机插口没声音的问题
  12. mp4box 编译与常用命令
  13. php工具箱mysql启动不_解决php工具箱(phpStudy)Apache启动成功,MySql无法启动的问题...
  14. 如何提高自己的工作能力 高效工作方法是绝效
  15. word中软回车和硬回车删除、替换
  16. 【reverse】buu-[WUSTCTF2020]level4——二叉树+IDA动态调试
  17. 学习Python真的能找到工作吗?
  18. vue element 表格增加删除修改数据
  19. DBeaver启动报错和DBeaver安装配置
  20. Android 机顶盒TV app开发

热门文章

  1. Koa2 中间件原理解析
  2. douyin pc端 x-bogus 参数分析
  3. Java二维数组,将古诗《相思》分别用横版和竖版的形式输出
  4. 1019. 数字黑洞
  5. android学习软件有哪些,推荐一款全中文安卓摩尔斯电码学习APP
  6. 开发人员需要学会持续性学习
  7. java ee 的使用方法_EE对话的NICE方法
  8. 气雾培智能管理计算机,丽水市农林院农业智能化快繁中心,气雾栽培,气雾培,鸟巢温室,克隆,植物克隆,克隆技术,植物非试管快繁技术,鱼菜共生,丽水农林院...
  9. L No 114514
  10. C语言核心编程-夏曹俊-专题视频课程