CF997C Sky Full of Stars

传送门

luogu

本题要求至少一行或一列为同一种颜色,可以转化为总方案数减去所有行和所有列不为同一种颜色

后面那个东西可以用容斥去做,枚举几行几列是同色的,然后剩下的格子随便取,方案为$$\sum_{i=0}{n}\sum_{j=0}(-1)^{i+j}\binom{n}{i}\binom{n}{j}\begin{cases} 3{i+j}3&i=0\ \mathrm{or} \ j=0\ 33^{(n-i)(n-j)}&otherwise\end{cases}$$

不要吐槽上面那坨式子qwqqwq

然后就可以\(O(n^2)\)了,但是无法通过此题.主要耗时是后面那个式子,把后面和j无关的东西丢到前面去,得$$3\sum_{i=1}{n}(-1)\binom{n}{i}\sum_{j=1}{n}(-1)\binom{n}{j}3^{(n-i)(n-j)}$$

注意到\(3^{(n-i)(n-j)}=(3^{n-i})^{n-j}\),可以联想到二项式定理\((x+y)^n=\sum_{i=0}^{n}\binom{n}{i}x^iy^{n-i}\),然后能得到$$3\sum_{i=1}{n}(-1)\binom{n}{i}((3{n-i}-1)n-3^{n-i})$$

(注意j从1开始)

没了

#include<bits/stdc++.h>
#define LL long long
#define il inline

using namespace std;
const int M=1e7+10,mod=998244353;
il LL rd()
{
    LL x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int n;
int fpow(int a,int b){int an=1;while(b){if(b&1) an=1ll*an*a%mod;a=1ll*a*a%mod,b>>=1;} return an;}
namespace ct3
{
    int fac[M],iac[M];
    int C(int n,int m){return m<0||n<m?0:1ll*fac[n]*iac[m]%mod*iac[n-m]%mod;}
    int ans;
    void wk()
    {
        fac[0]=1;
        for(int i=1;i<=n;++i) fac[i]=1ll*fac[i-1]*i%mod;
        iac[n]=fpow(fac[n],mod-2);
        for(int i=n;i;--i) iac[i-1]=1ll*iac[i]*i%mod;
        for(int i=1;i<=n;++i)
        {
            int x=(1ll*C(n,i)*(fpow(fpow(3,n-i)-1,n)-fpow(fpow(3,n-i),n))%mod+mod)%mod;
            ans=(ans+((i&1)?mod-x:x))%mod;
        }
        ans=1ll*ans*3%mod;
        for(int i=0;i<=n;++i)
        {
            int x=1ll*C(n,i)*fpow(3,i)%mod*fpow(fpow(3,n-i),n)%mod;
            ans=(ans+((i&1)?mod-x:x))%mod;
        }
        for(int j=1;j<=n;++j)
        {
            int x=1ll*C(n,j)*fpow(3,j)%mod*fpow(fpow(3,n),n-j)%mod;
            ans=(ans+((j&1)?mod-x:x))%mod;
        }
        printf("%d\n",(fpow(fpow(3,n),n)-ans+mod)%mod);
    }
}

int main()
{
    n=rd();
    ct3::wk();  //qwq
    return 0;
}
posted @ 2019-03-11 17:48  ✡smy✡  阅读(169)  评论(0编辑  收藏  举报