zoukankan      html  css  js  c++  java
  • Codeforces.997C.Sky Full of Stars(容斥 计数)

    题目链接
    那场完整的Div2(Div1 ABC)在这儿。。

    (Description)

      给定(n(nleq 10^6)),用三种颜色染有(n imes n)个格子的矩形,求至少有一行或一列格子同色的方案数。

    (Solution)

      求恰好有多少行/列满足同色不好求,但如果某几行/列已经确定同色,这些行/列外任意选择,即至少多少行/列满足,那么很好求。
      容斥。设(f(i,j))表示至少有(i)(j)列同色的方案数,则(ans=sum_{0leq ileq n}sum_{0leq jleq n}left[i+j>0 ight]C_n^iC_n^j(-1)^{i+j+1}f(i,j))
      当(i>0&&j>0)时,可以发现这(i)(j)列都是同色的,即(f(i,j)=3 imes 3^{(n-i)(n-j)})
      而当(i=0||j=0)时,假设(i=0),那么这(j)列间可任意组合,即(f(0,j)=3^j imes 3^{n imes(n-j)})
      后者可以(O(nlog n))计算,而前者至少需要(O(n^2))
      再化式子,令(i=n-i,j=n-j),则(i,j eq 0)时,$$egin{aligned}ans&=3sum_{i=0}^{n-1}sum_{j=0}^{n-1}C_n^{n-i}C_n^{n-j}(-1)^{2n-i-j-1}3^{ij}&=3sum_{i=0}^{n-1}sum_{j=0}^{n-1}C_n^iC_n^j(-1)^{i+j+1}3^{ij}end{aligned}$$
      把(i)提出来,看能不能直接算(j):$$egin{aligned}ans&=3sum_{i=0}^{n-1}C_n^i(-1)^{i+1}sum_{j=0}^{n-1}C_n^j(-1)^j(3^i)^j&=3sum_{i=0}^{n-1}C_n^i(-1)^{i+1}sum_{j=0}^{n-1}C_n^j(-3^i)^jend{aligned}$$
      由二项式定理((a+b)^n=sum_{k=0}^nC_n^ka^kb^{n-k})(j)的那一项可以直接化掉:$$ans=3sum_{i=0}^{n-1}C_n^i(-1)^{i+1}left[(1+(-3^i))^n-(-3^i)^n ight]$$
      于是就可以(O(nlog n))计算了。


      还有一个社会人的做法:https://www.cnblogs.com/Menhera/p/9277516.html


    //1107ms	7700KB
    #include <cstdio>
    #include <algorithm>
    #define mod (998244353)
    typedef long long LL;
    const int N=1e6+7;
    
    int C[N],inv[N];
    
    inline LL FP(LL x,int k)
    {
    	LL t=1;
    	for(; k; k>>=1,x=x*x%mod)
    		if(k&1) t=t*x%mod;
    	return t;
    }
    
    int main()
    {
    	int n; scanf("%d",&n);
    	LL ans1=0; C[0]=inv[1]=1;
    	for(int i=1; i<=n; ++i)
    	{
    		if(i>1) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    		C[i]=1ll*(n-i+1)*C[i-1]%mod*inv[i]%mod;
    		if(i&1) ans1+=1ll*C[i]*FP(3,(1ll*n*(n-i)+i)%(mod-1))%mod;//a^{varphi(p)}=1(mod p)
    		else ans1-=1ll*C[i]*FP(3,(1ll*n*(n-i)+i)%(mod-1))%mod;
    	}
    	ans1=2ll*ans1%mod;
    	LL ans2=0;
    	for(int i=0,pw3=1; i<n; ++i)
    	{
    		if(i&1) ans2+=1ll*C[i]*(FP(1+mod-pw3,n)-FP(mod-pw3,n))%mod;
    		else ans2-=1ll*C[i]*(FP(1+mod-pw3,n)-FP(mod-pw3,n))%mod;
    		pw3=3ll*pw3%mod;
    	}
    	printf("%I64d
    ",((ans1+3ll*ans2)%mod+mod)%mod);
    
    	return 0;
    }
    
  • 相关阅读:
    Eclipse调试Java的10个技巧
    什么是POJO?
    能够提高开发效率的Eclipse实用操作
    Oracle数据库查看执行计划
    Oracle执行计划详解
    Android接收wifi路由器发送过来的一组字节数据
    Android与路由器连接服务
    Android真机连接手机Target显示unknown cmd命令下adb devices 显示offline
    绿豆沙色值多少
    如何在Eclipse中添加Servlet-api.jar的方法
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9338517.html
Copyright © 2011-2022 走看看