zoukankan      html  css  js  c++  java
  • 题解:CF997 C.Sky Full of Stars

    Translation

    有一个 (n imes n (1 leq n leq 10^6)) 的正方形网格,用红色,绿色,蓝色三种颜色染色,求有多少种染色方案使得至少一行或一列是同一种颜色。结果对 (998244353) 取模。(翻译来自洛谷)

    Solution

    发现直接求很困难,考虑用容斥简化问题。

    发现约束条件「至少一行或一列是同一种颜色」是条件「对于任意 (i,j (i+j geq 1)) ,恰好 (i)(j) 列是同一颜色」的并集。

    (F(i,j)) 为满足条件「至少有 (i)(j) 列是同一颜色」的答案,不难发现,该条件是上句话后者的一个交集。

    根据容斥原理,答案能表示为:

    [sum_{i=0}^nsum_{j=0}^n [i+jgeq 1] imes (-1)^{i+j+1} {nchoose i} {nchoose j} F(i,j) ]

    根据基础组合数学知识 (F(i,j)) 的值为:

    [F(i,j)=left{ egin{aligned} & 3^i imes 3^{n(n-i)} & & j=0 \ & 3^j imes 3^{n(n-j)} & & i=0 \ & 3 imes 3^{(n-i)(n-j)} & & ext{otherwise} end{aligned} ight. ]

    先考虑 (i = 0)(j = 0) 的情况,直接套即可,答案为:

    [2cdotsum_{i=1}^n (-1)^{i+1} {nchoose i} 3^i cdot 3^{n(n-i)} ]

    复杂度 (mathcal{O}(n))

    然后是其他情况,暴力推式子:

    [egin{aligned} & sum_{i=1}^nsum_{j=1}^n (-1)^{i+j+1} {nchoose i} {nchoose j} 3cdot 3^{(n-i)(n-j)} \ = & 3 cdot sum_{i=1}^n (-1)^{i+1} {nchoose i} sum_{j=1}^n {nchoose j} (-1)^j (3^{n-i})^{n-j} \ = & 3 cdot sum_{i=1}^n (-1)^{i+1} {nchoose i} [(3^{n-i}-1)^n - 3^{n(n-i)}] end{aligned}]

    (前置知识:二项式定理,求和顺序变换)

    这样这一块是 (mathcal{O}(nlog_2 n)) 的。

    Code(C++):

    #include<bits/stdc++.h>
    #define forn(i,s,t) for(register int i=(s);i<=(t);++i)
    #define form(i,s,t) for(register int i=(s);i>=(t);--i)
    using namespace std;
    typedef long long LL;
    const int N = 1e6+3, Mod = 998244353;
    inline LL q_pow(LL p, LL k) {
    	LL Ans = 1;
    	while(k) {
    		(k & 1) && (Ans = Ans * p %Mod);
    		p = 1ll * p * p %Mod;
    		k >>= 1;
    	}
    	return Ans;
    }
    LL fac[N], inv[N];
    inline LL C(int n, int k) {
    	return 1ll * fac[n] * inv[k] %Mod * inv[n - k] %Mod;
    }
    int n; LL Ans, res, Pow3[N], Pown[N];
    int main() {
    	cin >> n;
    	fac[0] = 1;
    	forn(i,1,n) fac[i] = 1ll * i * fac[i-1] %Mod;
    	inv[n] = q_pow(fac[n], Mod - 2);
    	form(i,n,1) inv[i-1] = 1ll * i * inv[i] %Mod;
    	Pow3[0] = 1;
    	forn(i,1,n) Pow3[i] = Pow3[i-1] * 3ll %Mod;
    	Pown[0] = 1;
    	forn(i,1,n) Pown[i] = Pow3[n] * Pown[i-1] %Mod;
    	forn(i,1,n) {          // 情况 1
    		if(i & 1) Ans += C(n, i) * Pow3[i] %Mod * Pown[n-i] %Mod;
    		else Ans += Mod - C(n, i) * Pow3[i] %Mod * Pown[n-i] %Mod;
    		Ans %= Mod;
    	}
    	Ans = 2ll * Ans %Mod;
    	forn(i,1,n) {          // 情况 2
    		if(i & 1) res += C(n, i) * (q_pow((Pow3[n-i] - 1), n) - Pown[n-i] + Mod) %Mod;
    		else res += Mod - C(n, i) * (q_pow((Pow3[n-i] - 1), n) - Pown[n-i] + Mod) %Mod;
    		res %= Mod;
    	}
    	res = 3ll * res %Mod;
    	printf("%d
    ", (Ans + res) %Mod);
    	return 0;
    }
    
  • 相关阅读:
    node搭建文件服务器
    es6快速排序
    vue+koa+mysql简易demo
    linux常用命令
    su: Authentication failure 的解决方案
    安装gensim报错:Original error was: DLL load failed: 找不到指定的模块。 Command "python setup.py egg_info" failed with error code 1 in C:UsersxubingAppDataLocalTemppip-install-nta89iepgensim
    使用服务器上的Jupyter notebook。
    tf.nn.conv2d()需要搞清楚的几个变量。
    tf入门-池化函数 tf.nn.max_pool 的介绍
    tf入门-卷积步长strides参数的具体解释
  • 原文地址:https://www.cnblogs.com/Ax-Dea/p/14446508.html
Copyright © 2011-2022 走看看