【洛谷题解】P5159 WD与矩阵

传送门

如何用一句话描述:

给定n和m,求有多少种大小为n*m的01矩阵满足每行每列异或值都是0,答案对998244353取模


yy一下

我们考虑一个(n-1)*(m-1)的矩阵

很显然,如果我们随便填,会发生什么呢?

会有一个超级大的答案出来

可是这跟我们的问题有什么关系?

毫无关系

我们找个特例,比如n=4,m=4

我们可能构造出来一个矩阵是这样的:

1 0 1 ?
0 1 1 ?
0 0 0 ?
? ? ? ?

问题来了,?处填什么?

填之前的坑啊!

用这个栗子来说

最终我们胡搞搞出来得到的是:

1 0 1 0
0 1 1 0
0 0 0 0
1 1 0 0

发现了什么?

什么都没有发现

这个矩阵满足要求

在关注原来的“?”处

发现:

对于每一行最后一个,如果当前行1的个数为偶数,那么它为0,不然就是1
对于每一列最后一个,如果当前行1的个数为偶数,那么它为0,不然就是1

复制粘贴真好玩

不管怎么样,这样子是可以的,是能得到正解的

那么,对于处于右下角的呢?

可以证明,当那几个格子确定下来时,右下角的格子不会出现矛盾情况

但是我不会

于是,这就是一个简单的快速幂了

上代码!当当当当——

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

long long t;
long long n,m;

inline void read(long long &x)
{
    long long f=1;
    x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
        {
            f=-1;
        }
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    x*=f;
}

long long fast_pow(long long a,long long b,long long n)
{
    long long t,y;
    t=1;
    y=a;
    while(b!=0)
    {
        if(b&1==1)
        {
            t=t*y%n;
        }
        y=y*y%n;
        b=b>>1;
    }
    return t;
}

int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&m);
        long long ans;
        ans=fast_pow(2,(n-1)*(m-1),998244353);
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值