zoukankan      html  css  js  c++  java
  • codeforces 997-C. Sky Full of Stars


    题目链接

    https://codeforces.com/contest/997/problem/C

    题意

    给一个n*n的矩阵,要往每个格子涂rgb三种颜色之一。问有多少种涂色方案,满足至少有一列或者一行的颜色是相同的。

    分析

    ans=至少有一行的+至少有一列的-至少有一行且有一列的

    [ ans=2sum_{i=1}^{n} (-1)^{i+1} C^i_n imes 3^{(n-i)n} imes3^i -sum_{i=1}^{n}sum_{j=1}^{n}(-1)^{i+j}3 C_n^i C_n^j3^{(n-i)(n-j)} ]

    式子中第二项有两层求和可以通过二项式定理优化到一维。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1000050;
    ll fact[maxn],inv[maxn];
    const ll MOD=998244353;
    ll Pow(ll x,ll n){
    	ll ans=1,base=x%MOD;
    	while(n){
    		if(n&1) ans=ans*base%MOD;
    		base=base*base%MOD;
    		n>>=1;
    	}
    	return ans;
    }
    void init(){
    	fact[0]=1;
    	for(int i = 1; i < maxn; ++i)
    		fact[i]=fact[i-1]*i%MOD;
    	inv[maxn-1]=Pow(fact[maxn-1],MOD-2);
    	for(int i = maxn-2; i >= 0; --i)
    		inv[i]=inv[i+1]*(i+1)%MOD;
    }
    int main(){
    	init();
    	int n;
    	cin>>n;
    	ll ans=0;
        for(int i = 1; i <= n; ++i){
            ll t=fact[n]*inv[i]%MOD*inv[n-i]%MOD*Pow(3,(ll)n*(n-i)+i)%MOD;
            if(i%2==0) t=-t;
            ans=(ans+t)%MOD;
            if(ans>=MOD) ans-=MOD;
            else if(ans<0) ans+=MOD;
        }
        ans=ans*2%MOD;
    	ll p=1;
    	for(int i = 0; i < n; ++i){
    		ll t=fact[n]*inv[i]%MOD*inv[n-i]%MOD*3%MOD*(Pow(1-p,n)-Pow(-p,n))%MOD;
    		if(i%2==0) t=-t;
    		p=p*3%MOD;
    		ans=(ans+t)%MOD;
    		if(ans>=MOD) ans-=MOD;
            else if(ans<0) ans+=MOD;
    	}
    	cout<<(ans%MOD+MOD)%MOD<<endl;
    	return 0;
    }
    
    
  • 相关阅读:
    sh_02_判断年龄改进版
    面向对象-内置函数和内置方法
    python面向对象-三大特性
    面向对象编程
    面向对象编程-回合制游戏
    练习Dream-购物车
    bytes和str的区别与转换
    字符串的操作和使用方法。
    程序员必须掌握的600个单词
    移动端的网页设计流程有哪些?
  • 原文地址:https://www.cnblogs.com/sciorz/p/9254774.html
Copyright © 2011-2022 走看看