• abc242 F Black and White Rooks


    放置事实上等同于 2 种颜色所覆盖到的行、列集合没交。

    考虑枚举 2 种颜色各自放置的行列。

    \[\sum_{i,j}f[i][j]*g[i][j]*\binom{n}{i+x}*\binom{i+x}{i}*\binom{m}{j+y}*\binom{j+y}{j} \]

    \(f[i][j]\) 为选择的黑色点仅包含 \(i\)\(j\) 列的方案数。

    考虑仅包含,那么显然选择的是 \(i\)\(j\) 列交的矩形,即 \(f[i][j]=\binom{ij}{B}\)

    考虑对于一个小的方案可能会在大的方案贡献到,那么我们所选择的必须没有一行、一列是空的。这个的话发现是恰好,可以类似于 这道题,直接用二项式反演。
    或者使用递推,减去实际占的行列不够的。

    二项式反演

    #include <bits/stdc++.h>
    #define int long long
    #define pb push_back
    using namespace std;
    #define N 2502
    const int mod=998244353;
    int fpow(int x,int y) {
    	int res=1;
    	while(y) {
    		if(y&1) res=res*x%mod; y>>=1; x=x*x%mod;
    	}
    	return res;
    }
    int f[52][52],g[52][52],a[52][52],b[52][52],jie[N],djie[N],n,m,B,W;
    
    int C(int n,int m) {
    	if(m>n||n<=0||m<0) return 0;
    	return jie[n]*djie[m]%mod*djie[n-m]%mod;
    }
    
    signed main() {
    	cin.tie(0); ios::sync_with_stdio(false);
    	jie[0]=djie[0]=1; for(int i=1;i<=2500;i++) jie[i]=jie[i-1]*i%mod,djie[i]=fpow(jie[i],mod-2);
    	cin>>n>>m>>B>>W;
    	for(int x=1;x<=n;x++) {
    		for(int y=1;y<=m;y++) {
    			for(int i=0;i<=x;i++) {
    				for(int j=0;j<=y;j++) {
    					a[i][j]=C(x,i)*C(y,j)%mod*C(x*y-(i*y+j*x-i*j),B)%mod;
    				}
    			}
    			int qwq=0;
    			for(int i=0;i<=x;i++) {
    				for(int j=0;j<=y;j++) {
    					qwq=(qwq+(((i+j)&1)?-1:1)*a[i][j]%mod)%mod;
    				}
    			}
    			f[x][y]=qwq; 
    //			cout<<qwq<<' ';
    		} 
    //		cout<<'\n';
    	}
    	for(int x=1;x<=n;x++) {
    		for(int y=1;y<=m;y++) {
    			for(int i=0;i<=x;i++) {
    				for(int j=0;j<=y;j++) {
    					a[i][j]=C(x,i)*C(y,j)%mod*C(x*y-(i*y+j*x-i*j),W)%mod;
    				}
    			}
    			int qwq=0;
    			for(int i=0;i<=x;i++) {
    				for(int j=0;j<=y;j++) {
    					qwq=(qwq+(((i+j)&1)?-1:1)*a[i][j]%mod)%mod;
    				}
    			}
    			g[x][y]=qwq; 
    //			cout<<qwq<<' ';
    		} 
    //		cout<<'\n';
    	}
    	int ans=0;
    	for(int i=1;i<=n;i++) {
    		for(int j=1;j<=m;j++) {
    			for(int x=1;x<=n;x++) {
    				for(int y=1;y<=m;y++) {
    					ans=(ans+f[i][j]*g[x][y]%mod*C(n,i+x)%mod*C(i+x,i)%mod*C(m,j+y)%mod*C(j+y,j)%mod)%mod;
    				}
    			}
    		}
    	}
    	ans=(ans%mod+mod)%mod; cout<<ans;
    	return 0;
    }
    
    

    递推

    #include <bits/stdc++.h>
    #define int long long
    #define pb push_back
    using namespace std;
    #define N 2502
    const int mod=998244353;
    int fpow(int x,int y) {
    	int res=1;
    	while(y) {
    		if(y&1) res=res*x%mod; y>>=1; x=x*x%mod;
    	}
    	return res;
    }
    int f[52][52],g[52][52],jie[N],djie[N],n,m,b,w;
    
    int C(int n,int m) {
    	if(m>n||n<=0||m<0) return 0;
    	return jie[n]*djie[m]%mod*djie[n-m]%mod;
    }
    
    signed main() {
    	cin.tie(0); ios::sync_with_stdio(false);
    	jie[0]=djie[0]=1; for(int i=1;i<=2500;i++) jie[i]=jie[i-1]*i%mod,djie[i]=fpow(jie[i],mod-2);
    	cin>>n>>m>>b>>w;
    	for(int i=1;i<=n;i++) {
    		for(int j=1;j<=m;j++) {
    			f[i][j]=C(i*j,b);
    //			if(!f[i][j]) continue ;
    			for(int x=1;x<=i;x++) {
    				for(int y=1;y<=j;y++) {
    					if(x==i&&y==j) continue ;
    					f[i][j]=(f[i][j]-f[x][y]*C(i,x)%mod*C(j,y)%mod)%mod;
    				}
    			}
    //			if(f[i][j]<0) f[i][j]=0;
    //			cout<<f[i][j]<<" ";
    		}
    //		cout<<'\n';
    	}
    	for(int i=1;i<=n;i++) {
    		for(int j=1;j<=m;j++) {
    			g[i][j]=C(i*j,w);
    //			if(!g[i][j]) continue ;
    			for(int x=1;x<=i;x++) {
    				for(int y=1;y<=j;y++) {
    					if(x==i&&y==j) continue ;
    					g[i][j]=(g[i][j]-g[x][y]*C(i,x)%mod*C(j,y)%mod)%mod;
    				}
    			}
    //			if(g[i][j]<0) g[i][j]=0;
    //			cout<<g[i][j]<<" ";
    		}
    //		cout<<'\n';
    	}
    	int ans=0;
    	for(int i=1;i<=n;i++) {
    		for(int j=1;j<=m;j++) {
    			for(int x=1;x<=n;x++) {
    				for(int y=1;y<=m;y++) {
    					ans=(ans+f[i][j]*g[x][y]%mod*C(n,i+x)%mod*C(i+x,i)%mod*C(m,j+y)%mod*C(j+y,j)%mod)%mod;
    				}
    			}
    		}
    	}
    	ans=(ans%mod+mod)%mod; cout<<ans;
    	return 0;
    }
    
    
  • 相关阅读:
    Codeforces Gym 100571A A. Cursed Query 离线
    codeforces Gym 100500 J. Bye Bye Russia
    codeforces Gym 100500H H. ICPC Quest 水题
    codeforces Gym 100500H A. Potion of Immortality 简单DP
    Codeforces Gym 100500F Problem F. Door Lock 二分
    codeforces Gym 100500C D.Hall of Fame 排序
    spring data jpa 创建方法名进行简单查询
    Spring集成JPA提示Not an managed type
    hibernate配置文件中的catalog属性
    SonarLint插件的安装与使用
  • 原文地址:https://www.cnblogs.com/xugangfan/p/15971266.html
Copyright © 2020-2023  润新知