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


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

    题面

    用3种颜色对(n×n)的格子染色,问至少有一行或一列只有一种颜色的方案数。((n≤10^6))

    分析

    显然任意染色的方案数为(3^{n^2}),我们考虑求出没有一行一列只有一种颜色的方案数,然后相减。

    (1)首先考虑仅仅没有全部是一种颜色的列,每一列任意染色有(3^n)种方案,去掉每一列只有一种颜色的方案有3种,共(3^n-3)种,n列就有((3^n-3)^n)种。

    (2)再考虑仅仅没有全部是一种颜色的行,考虑枚举只有一种颜色的行数i,其他行任意填。但会有重复计算的情况,比如i=1的时候,有1行颜色相同。但其他行任意填的时候可能会又填出一种颜色的一行,有2行颜色相同,要减掉。所以考虑容斥原理。

    ​ $$tot=sum_{i=1}^n (-1)^i C_n^i f(i)$$,其中(C_n^i)表示从n行中选出i行,((-1)^i)用来容斥,(f(i))表示有i行颜色相同的方案数

    现在我们来推导(f(i)),注意我们不能产生只有一种颜色的列,只能产生只有一种颜色相同的行

    ​ (2.1)如果这i行颜色相同,我们要从3种颜色种选一种给i行上色。然后对于这i行下方的n小列(长度为n-i),我们任意涂色,但要注意不能涂与上面i行相同的颜色,否则会造成有颜色相同的列,与情况(1)重复。那么每列方案数((3^{n-i}-1)),n列方案数((3^{n-i}-1)^n),总方案数(3(3^{n-i}-1)^n)

    ​ (2.2)如果这i行颜色不同,那么i行有(3^i-3)种方案,其中3种是i行颜色相同的方案。剩下的(n(n-i))格任意涂色。显然不会产生颜色相同的列,总方案数(3^{n(n-i)}(3^i-3))

    ​ 因此(f(i)=3(3^{n-i}-1)^n+3^{n(n-i)}(3^i-3))

    代入表达式,我们可以得到最终答案

    [ans=3^{n^2}-(3^n-3)^n-sum_{i=1}^n (-1)^i C_n^i(3(3^{n-i}-1)^n+3^{n(n-i)}(3^i-3)) ]

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1000000
    #define mod 998244353
    using namespace std;
    typedef long long ll;
    int n;
    ll fact[maxn+5],invfact[maxn+5];
    inline ll fast_pow(ll x,ll k){
        ll ans=1;
        while(k){
            if(k&1) ans=ans*x%mod;
            x=x*x%mod;
            k>>=1;
        }
        return ans;
    }
    inline ll inv(ll x){
        return fast_pow(x,mod-2);
    }
    inline ll C(int n,int m){
        if(n<m) return 0;//小心特殊情况 
        if(n==m) return 1;
        if(m==0) return 1;
        return fact[n]*invfact[n-m]%mod*invfact[m]%mod;
    }
    
    void pre_work(int n){
        fact[0]=1;
        for(int i=1;i<=n;i++) fact[i]=fact[i-1]*i%mod;
        for(int i=0;i<=n;i++) invfact[i]=inv(fact[i]);
    }
    
    
    int main(){
    	scanf("%d",&n);
    	pre_work(n);
    	ll ans=0;
    	ans=fast_pow(3,(ll)n*n);
    	ans=(ans-fast_pow(fast_pow(3,n)-3,n)+mod%mod);
    	for(int i=1;i<=n;i++){
    		ll now=fast_pow(-1,i)*C(n,i)%mod*(3*fast_pow(fast_pow(3,n-i)-1,n)%mod+(fast_pow(3,i)-3+mod)*fast_pow(3,(ll)n*(n-i))%mod)%mod;
    		ans=(ans-now+mod)%mod;
    	}
    	printf("%I64d
    ",ans);
    }
    
  • 相关阅读:
    读书笔记 《如何阅读一本书》
    蓝桥杯 试题 历届试题 翻硬币 反转(开关问题)
    读书笔记 《如何阅读一本书》
    蓝桥杯 试题 历届试题 高僧斗法 博弈论
    读书笔记 《如何阅读一本书》
    蓝桥杯 试题 历届试题 格子刷油漆
    读书笔记 《如何阅读一本书》
    读书笔记 《如何阅读一本书》
    读书笔记 《如何阅读一本书》
    读书笔记 《如何阅读一本书》
  • 原文地址:https://www.cnblogs.com/birchtree/p/11205134.html
Copyright © 2020-2023  润新知