• P5857 「SWTR-03」Matrix


    原本自己有一个思路的,推了半天不太确定看了下题解,发现到后面完全不知道他代码在写些什么(我太弱了),所以打算自己理一下。

    题解

    首先我们可以肯定的一点就是,我们可以发现,一个矩阵的形态只和他横着和竖着有多少行和列被转化了奇数次,而与剩下的都没有关系。

    很显然的可以发现行和列是可以独立计算再相乘的,考虑如何计算单行和单列的贡献。

    以行为例,我们可以枚举他有多少个奇数的位置,发现奇数位置的数量 (i) 必须满足如下的性质:

    [ile k\ ile n\ i equiv k pmod{2} ]

    但是发现可能有一种特殊情况,就是当 (n-i)(m-j) 也合法的时候,两者形成的矩形是完全一样的,需要把这一部分的消去。

    应该就这些了。

    代码如下

    #include<bits/stdc++.h>
    using namespace std;
    #define Lint long long
    const int N=2e5+5;
    const Lint MOD=998244353;
    const Lint Inv=499122177;
    int n,m,k;Lint res=0;
    Lint fac[N],ifac[N];
    Lint cnt1[2],cnt2[2];
    Lint ksm(Lint x,int k)
    {
    	Lint res=1;
    	for(;k;k>>=1,x=x*x%MOD)
    	if(k&1) res=res*x%MOD;
    	return res;
    }
    Lint cal(int n,int m){return fac[n]*ifac[m]%MOD*ifac[n-m]%MOD;}
    void solve()
    {
    	cin>>n>>m>>k,res=0;
    	Lint res1=0,res2=0;
    	for(int i=k%2;i<=n&&i<=k;i+=2) res1+=cal(n,i),res1%=MOD;
    	for(int i=k%2;i<=m&&i<=k;i+=2) res2+=cal(m,i),res2%=MOD;
    	res+=res1*res2%MOD;
    	if(n%2==0&&m%2==0)
    	{
    		res1=res2=0;
    		for(int i=max(n-k,k&1);i<=n&&i<=k;i+=2) res1+=cal(n,i),res1%=MOD;
    		for(int i=max(m-k,k&1);i<=m&&i<=k;i+=2) res2+=cal(m,i),res2%=MOD;
    		res-=res1*res2%MOD*Inv%MOD,res=(res+MOD)%MOD;
    	}
    	printf("%lld
    ",res);
    }
    int main()
    {
    	fac[0]=ifac[0]=1;
    	for(int i=1;i<N;++i) fac[i]=fac[i-1]*i%MOD;
    	for(int i=1;i<N;++i) ifac[i]=ksm(fac[i],MOD-2);
    	int T;cin>>T;
    	while(T--) solve();
    }
    
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    开源数据库在平安的应用实践
    从Oracle到PostgreSQL:Storage Index 特性 vs BRIN 索引
    Cosmos 白皮书
    基于支付场景下的微服务改造与性能优化
    MySQL数据库备份之主从同步配置
    Maven Gradle 区别
    荐书:《PostgreSQL指南:内幕探索》| 留言送书
    SQL、NoSQL、NewSQL,论开源之路谁主沉浮
  • 原文地址:https://www.cnblogs.com/Point-King/p/14070299.html
Copyright © 2020-2023  润新知