题目链接


\(Description\)

给定一个\(n\times m\)的\(01\)矩阵。求任意选出\(r\)行、\(c\)列(共\(2^{n+m}\)种方案),使得这\(r\)行\(c\)列的交的位置的\(r\times c\)个数的和为奇数,的方案数有多少。

(...我也不知道怎么就表述成这样了,反正挺好理解)

\(n,m\leq300\)。

\(Solution\)

假设已经确定了选择某些行,然后把每一行\(m\)个数看做一个\(m\)位二进制数。

如果这些行异或和为\(0\),那怎么选列也不行。

否则每一列异或这些行是\(0\)还是\(1\)是确定的。假设有\(a\)列异或后为\(1\),\(b\)列异或后为\(0\),\(a+b=m\)。我们要从\(a\)中选出奇数个,从\(b\)中随便选,那么方案数是\(2^{a-1}\cdot2^b=2^{m-1}\)(从\(n\)中选出奇数个数的方案数。。\(C_n^1+C_n^3+C_n^5+...=\frac{2^n}{2}=2^{n-1}\))。

也就是不管行怎么选,只要异或和不为\(0\),列就有\(2^{m-1}\)种方案。

异或和不为\(0\)的方案数=\(2^n-\)异或和为\(0\)的方案数。异或和为\(0\)的方案数可以用线性基求,是\(2^{n-r}\)(\(n\)是元素总数,\(r\)是矩阵的秩,也就是线性基中的元素个数),所以答案就是\((2^n-2^{n-r})\cdot2^{m-1}\)。

这里线性基插入还是一样的,把一行看做\(m\)位数就好了。

复杂度\(O(n^3)\)或\(O(\frac{n^3}{w})\)。


//7ms	896KB
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define mod 998244353
typedef long long LL;
const int N=305; int A[N][N],B[N][N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline int FP(int x,int k)
{
int t=1;
for(; k; k>>=1,x=1ll*x*x%mod)
if(k&1) t=1ll*t*x%mod;
return t;
} int main()
{
int n=read(),m=read();
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j) A[i][j]=read();
int r=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
if(A[i][j])//x>>j&1
{
if(B[j][j]) for(int k=j; k<=m; ++k) A[i][k]^=B[j][k];
else
{
for(int k=j; k<=m; ++k) B[j][k]=A[i][k];
++r; break;
}
}
printf("%d\n",(FP(2,n+m-1)+mod-FP(2,n-r+m-1))%mod); return 0;
}

bitset优化:

//5ms	256KB
#include <cstdio>
#include <cctype>
#include <bitset>
#include <algorithm>
#define gc() getchar()
#define mod 998244353
typedef long long LL;
const int N=305; std::bitset<N> A[N],B[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline int FP(int x,int k)
{
int t=1;
for(; k; k>>=1,x=1ll*x*x%mod)
if(k&1) t=1ll*t*x%mod;
return t;
} int main()
{
int n=read(),m=read();
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j) A[i][j]=read()==1;
int r=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
if(A[i][j])//x>>j&1
{
if(B[j][j]) A[i]^=B[j];
else
{
B[j]=A[i];
++r; break;
}
}
printf("%d\n",(FP(2,n+m-1)+mod-FP(2,n-r+m-1))%mod); return 0;
}

Yahoo Programming Contest 2019.E.Odd Subrectangles(思路 线性基)的更多相关文章

  1. Yahoo Programming Contest 2019 E - Odd Subrectangles

    E - Odd Subrectangles 思路: 对于行方案固定的情况下,假设和为奇数的列为a个,和为偶数的列为b个,a+b = m 那么从奇数里面选奇数个,即C(a, 1) + C(a, 3) + ...

  2. [AtCoder] Yahoo Programming Contest 2019

    [AtCoder] Yahoo Programming Contest 2019   很遗憾错过了一场 AtCoder .听说这场是涨分场呢,于是特意来补一下题. A - Anti-Adjacency ...

  3. Yahoo Programming Contest 2019 补题记录(DEF)

    D - Ears 题目链接:D - Ears 大意:你在一个\(0-L\)的数轴上行走,从整数格出发,在整数格结束,可以在整数格转弯.每当你经过坐标为\(i-0.5\)的位置时(\(i\)是整数),在 ...

  4. 【AtCoder】Yahoo Programming Contest 2019

    A - Anti-Adjacency K <= (N + 1) / 2 #include <bits/stdc++.h> #define fi first #define se se ...

  5. Atcoder Yahoo Programming Contest 2019 简要题解

    A-C 直接放代码吧. A int n,k; int main() { n=read();k=read(); puts(k<=(n+1)/2?"YES":"NO&q ...

  6. Yahoo Programming Contest 2019 F - Pass

    F - Pass 思路: dp[i][j] 表示到第 i 个球为止放了 j 个蓝球的方案数 第 i 个球来自的位置的最右边是min(i, n) 转移方程看代码 代码: #pragma GCC opti ...

  7. Yahoo Programming Contest 2019 D - Ears

    D - Ears 思路: s:起点           t:终点           l:左端点           r:右端点 以上称为关键点 dp[i][j]表示到位置 i 为止,已经经过前 j ...

  8. Yahoo Programming Contest 2019

    A - Anti-Adjacency 签. #include <bits/stdc++.h> using namespace std; int main() { int n, k; whi ...

  9. Yahoo Programming Contest 2019 自闭记

    A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...

随机推荐

  1. ajax---异步请求对象的属性和方法

    方法: 1).open(method.url,asyn):创建请求,(post.get)asyn:表示同步(false)还是异步(true)提交 ,默认true 2)send(body) 发送请求,b ...

  2. JAVA中的Token

    JAVA中的Token 基于Token的身份验证 来源:转载 最近在做项目开始,涉及到服务器与安卓之间的接口开发,在此开发过程中发现了安卓与一般浏览器不同,安卓在每次发送请求的时候并不会带上上一次请求 ...

  3. IDEA创建第一个项目详细过程

  4. 三 os模块

    os模块是与操作系统交互的一个接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相 ...

  5. 金蝶k3密码批量修改

    该字段含有单引号,直接使用查询语句,需要转义其中的单引号.select * from t_User where FSID = ') F ", ,P T #8 *P!D &D 80!N ...

  6. Java开发环境笔记

    在配置环境变量中 设置Java_home: 一是为了方便引用,比如,jdk安装在c:\jdk16.0目录里,则设置java_home为该目录路径,那么以后要使用这个路径的时候,只需输入%java_ho ...

  7. base | Tread类

    Tread类 Linux中,每个进程有一个pid,类型pid_t,由getpid()取得.Linux下的POSIX线程也有一个id,类型 pthread_t,由pthread_self()取得,该id ...

  8. rsa证书ssh登陆服务器

    好久不用,又生疏了. 今晚实操了一下,作一个记录. 使用rsa的密钥对登陆linux服务器,主要是为了安全. 这种证书级别的登陆,比最复杂的root用户名和帐号的安全性都要高一个等级. 至少服务器不会 ...

  9. Java基础知识➣泛型整理(四)

    概述 泛型的本质是参数化类型,使用同一套代码来满足不同数据类型的业务需要,提高代码的执行效率,使代码简单明了. 泛型方法 该方法在调用时可以接收不同类型的参数.根据传递给泛型方法的参数类型,编译器适当 ...

  10. bzoj2683&&bzoj4066

    题解: 前一题不是强制在线,后一题是强制在线 树套树空间会炸 说一下cdq分治+树状数组 首先我们利用cdq分治使得查询和操作保证先后关系 然后矩阵查询变成4个矩阵的差 那么我们就可以运用扫描线的方法 ...