zoukankan      html  css  js  c++  java
  • 容斥

    题面

    给一个 n*m 的矩阵染色, 每个点可以染 k 种颜色, 求没有任意一行或任意一列颜色相同的方案数。答案对 998244353 取模。

    容斥。
    枚举有 i 行 j 列同色的方案数,并乘上(-1)^{i+j} 加入答案。//容斥原理,有加有减
    令 f(i; j) 为 i 行 j 列同色,同色的行列所能取的颜色方案数。
    i = 0; j = 0 时, f(i; j) = 1         //没有点,自然只有一种选择。
    i = 0; j > 0 时, f(i; j) = k^{j}       //只有列有同色,每一列有k种选择,共j列
    i > 0; j = 0 时, f(i; j) = k^{i}       //同上
    i > 0; j > 0 时, f(i; j) = k        //这i行j列颜色都一样,只有k种选择
    答案为 sum_{i=0}^{n}sum_{j=0}^{m}(-1)^{i+j}*_{n}^{i}	extrm{C}_{m}^{j}	extrm{C} * f(i; j) *k^{(n-i)(m-j)}
    对于 i = 0 或 j = 0 的情况可以暴力计算,考虑 i 和 j 都大于 0 的情况。
    k sum_{i-1}^{n}sum_{j=1}^{m}(-1)^{(i+j)}*_{n}^{i}	extrm{C}_{m}^{j}	extrm{C}* k^{(n-i)(m-j)}
    = k sum_{i-1}^{n}(-1)^{i} _{n}^{i}	extrm{C}sum_{j=1}^{m}(-1)^{j} _{m}^{j}	extrm{C} ·k^{(n-i)(m-j)}
    = k sum_{i-1}^{n}(-1)^{i} _{n}^{i}	extrm{C}​​​​​​​sum_{j=1}^{m}(-1)^{j} _{m}^{j}	extrm{C} · k^{(n-i)^{(m-j)}}
    = k sum_{i-1}^{n}(-1)^{i}​​​​​​​ _{n}^{i}	extrm{C}​​​​​​​((k^{(n-i)}-1)^{m} - (k^{n-i})^{m})
    就可以利用快速幂计算了。

    代码

    #include<iostream>
    using namespace std;
    const long long MOD=998244353,MOD2=MOD-1;
    const int N=1010000;
    long long n,m,k,fac[N],inv[N];
    long long pow(long a,long b){//快速幂 
        a=(a%MOD+MOD)%MOD,b=(b%MOD2+MOD)%MOD2;
        long long r=1;
        while(b){
            if(b&1) r=r*a%MOD;
            a=a*a%MOD,b<<=1;
        }
        return r;
    }
    long long C(int n,int m){//组合数 
        if(n<0||m<0||n-m<0) return;
        return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
    }
    int main(){
        fac[0]=1;
        for(int i=1;i<=1000000;i++)
            fac[i]=fac[i-1]*i%MOD;//阶乘
        inv[0]=inv[1]=1;//逆元
        for(int i=2;i<=1000000;i++)
            inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD;
        for(int i=1;i<=1000000;i++)
            inv[i]=inv[i-1]*inv[i]%MOD;
        cin>>n>>m>>k;
        long long ans=pow(k,n*m);//所有的情况 
        for(int i=1;i<=n;i++)//暴力求只有横行同色 
            if(i&1)//容斥原理,奇减偶加 
                ans=(ans-C(n,i)*pow(k,i)%Mod*pow(k,(n-i)*m)%MOD+MOD)%MOD;
            else
                ans=(ans+C(n,i)*pow(K,i)%MOD*pow(K,(n-i)*m)%MOD)%MOD;
        for(int i=1;i<=m;i++)//暴力求只有竖列同色 
            if(i&1)
                ans=(ans-C(m,i)*pow(K,i)%MOD*pow(K,(m-i)*n)%MOD+MOD)%MOD;
            else
                ans=(ans+C(m,i)*pow(K,i)%MOD*pow(K,(m-i)*n)%MOD)%MOD;
        for(int i=1;i<=n;i++)//求既有行又有列同色 
            if(i&1)
                ans=(ans-C(n,i)*K%MOD*((pow(pow(K,n-i)-1,m)-pow(K,(n-i)*m)+MOD)%MOD)%MOD+MOD)%MOD;
            else
                ans=(ans+C(n,i)*K%MOD*((pow(pow(K,n-i)-1,m)-pow(K,(n-i)*m)+MOD)%MOD)%MOD)%MOD;
        cout<<ans;
        return 0;
    }

     欢迎指正评论O(∩_∩)O~~

  • 相关阅读:
    bzoj 3339 莫队
    E. XOR and Favorite Number
    HDU 2222 AC自动机
    SPOJ 694 不同子串个数
    Codeforces Round #428 (Div. 2)
    HDU 6103
    《贪婪的动态规划》
    《浅谈图论模型的建立与应用》
    bzoj 2194 快速傅里叶之二
    java中高级面试题整理及参考答案
  • 原文地址:https://www.cnblogs.com/kylinbalck/p/9795781.html
Copyright © 2011-2022 走看看