[CF1672G]Cross Xor
G - Cross Xor
对于\((n\&1)\&\&(m\&1)\)的情况,所有行、列的异或和的必须相等(异或和指当前行/列中所有元素的异或和)
每次修改的点\((x_1,y_1)\),\((x_2,y_1)\),\((x_1,y_2)\),\((x_2,y_2)\)使得所有行和列的异或和不会改变
只对\((i,j)\)进行一次操作,那么所有行和列的异或和都会改变
对于\(n\)和\(m\)一奇一偶同理,此时只需要行(\(m\&1\))或者列(\(n\&1\))的异或和相等
然后对于\((n\&1)\&\&(m\&1)\)的解法:
将每一行每一列看作一个点,有\(?\)就连接着两个点,那么对于生成的图,考虑随便找出一棵生成树,那么我们的目的就是让所有点的权值(即其对应的异或和)相等,我们钦定所有点的权值为\(x(x=0/1)\),若当前点的权值不为\(x\),那么将其连向父亲的边的权值改成\(1\),这样这个点与其父亲的权值都要\(xor\ 1\),那么无论生成树外的边如何选择,生成树上的边总有唯一一种选择使得合法,所以答案是 \(2^{边数−点数+1}\),对每个连通块分别做一次即可
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=2e3+5,MOD=998244353;
int n,m,a[N][N],cnt_all;
int val[N<<1],vval[N<<1],c[N][N],cnt2[N];
int dp[2],prod[2];
vector<int> edge[N<<1];
int power(int x,int y){
int ans=1;
for(;y;y>>=1,x=1ll*x*x%MOD) if(y&1) ans=1ll*ans*x%MOD;
return ans;
}
int add(int x,int y){ x+=y; if(x>=MOD) x-=MOD; return x; }
void ad(int &x,int y){ x+=y; if(x>=MOD) x-=MOD; }
int now,num_edge,num_point;
bool flag,vis[N<<1];
void dfs(int u,int fa){
vis[u]=true,++num_point;
for(auto v:edge[u]){
++num_edge;
if(!vis[v]) dfs(v,u);
if(flag) return;
}
if(val[u]^now){
if(!fa) return flag=true,void();
val[u]^=1,val[fa]^=1;
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
getchar();
for(int j=1;j<=m;++j) a[i][j]=min(getchar()-'0',2),cnt_all+=(a[i][j]==2);
}
if(!(n&1)&&!(m&1)) return printf("%d",power(2,cnt_all)),0;
if((n&1)&&!(m&1)){
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
if(a[i][j]<2) val[j]^=a[i][j];
else ++cnt2[j];
}
for(int i=0;i<=max(n,m);++i){
c[i][0]=1;
for(int j=1;j<=i;++j) c[i][j]=add(c[i-1][j],c[i-1][j-1]);
}
prod[0]=prod[1]=1;
for(int i=1;i<=m;++i){
dp[0]=dp[1]=0;
for(int j=0;j<=cnt2[i];++j) ad(dp[val[i]^(j&1)],c[cnt2[i]][j]);
prod[0]=1ll*prod[0]*dp[0]%MOD,prod[1]=1ll*prod[1]*dp[1]%MOD;
}
return printf("%d",add(prod[0],prod[1])),0;
}
if(!(n&1)&&(m&1)){
for(int i=0;i<=n;++i)
for(int j=1;j<=m;++j){
if(a[i][j]<2) val[i]^=a[i][j];
else ++cnt2[i];
}
for(int i=0;i<=max(n,m);++i){
c[i][0]=1;
for(int j=1;j<=i;++j) c[i][j]=add(c[i-1][j],c[i-1][j-1]);
}
prod[0]=prod[1]=1;
for(int i=1;i<=n;++i){
dp[0]=dp[1]=0;
for(int j=0;j<=cnt2[i];++j) ad(dp[val[i]^(j&1)],c[cnt2[i]][j]);
prod[0]=1ll*prod[0]*dp[0]%MOD,prod[1]=1ll*prod[1]*dp[1]%MOD;
}
return printf("%d",add(prod[0],prod[1])),0;
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
if(a[i][j]<2) val[i]^=a[i][j],val[j+n]^=a[i][j],vval[i]=val[i],vval[j+n]=val[j+n];
else edge[i].pb(j+n),edge[j+n].pb(i);
}
int prod=1,ans=0;
for(int i=1;i<=n+m;++i)
if(!vis[i]){
flag=num_edge=num_point=0,dfs(i,0);
if(flag){ prod=0; break; }
num_edge/=2,prod=1ll*prod*power(2,num_edge-num_point+1)%MOD;
}
ad(ans,prod);
prod=now=1; for(int i=1;i<=n+m;++i) val[i]=vval[i],vis[i]=false;
for(int i=1;i<=n+m;++i)
if(!vis[i]){
flag=num_edge=num_point=0,dfs(i,0);
if(flag){ prod=0; break; }
num_edge/=2,prod=1ll*prod*power(2,num_edge-num_point+1)%MOD;
}
printf("%d",add(ans,prod));
return 0;
}
[CF1672G]Cross Xor的更多相关文章
- SQL Server 2008 R2——CROSS APPLY 根据数据出现的次数和时间来给新字段赋值
=================================版权声明================================= 版权声明:原创文章 禁止转载 请通过右侧公告中的“联系邮 ...
- 题解-CF617E XOR and Favorite Number
题面 CF617E XOR and Favorite Number 给定 \(n,m,k\) 和 \(n\) 个数的序列 \(a_i\),\(m\) 次求区间 \([l,r]\) 中异或值为 \(k\ ...
- [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...
- CROSS APPLY应用实例
--功能说明:统计每个人的平均分数,新字段[AVG_Score]根据PersonID链接到原表[tbiz_AssScore]上 SELECT [ID] ,[ProjectID] ,[PersonID] ...
- Domino----The Address Book does not contain a cross certificate capable of validating the public key.
The Address Book does not contain a cross certificate capable of validating the public key. 地址本不包含交叉 ...
- 二分+DP+Trie HDOJ 5715 XOR 游戏
题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- SQL Server中CROSS APPLY和OUTER APPLY的应用详解
SQL Server数据库操作中,在2005以上的版本新增加了一个APPLY表运算符的功能.新增的APPLY表运算符把右表表达式应用到左表表达式中的每一行.它不像JOIN那样先计算那个表表达式都可以, ...
- 交叉验证(Cross Validation)原理小结
交叉验证是在机器学习建立模型和验证模型参数时常用的办法.交叉验证,顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏. ...
- T-SQL CROSS APPLY、MERGE
写在前面 刚才看项目里一个存储过程,也是好长时间没有使用Sql Server2008了,好多写法和函数感觉到陌生,这就遇到了CROSS APPLY 和MERGE的语法,两者之前完全没接触过. 所以专门 ...
- BZOJ 2115 【Wc2011】 Xor
Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...
随机推荐
- 初识if,if的三种结构
1.if语句 流程控制语句:通过一语句,来控制程序的执行流程.其中if属于分支结构 2.if语句的第一种格式 . 实操: 3.if的第二种格式 实操: 4.if的第三种格式 实操: 5.注意事项 在i ...
- 【Python】配置pip使用国内镜像源
配置pip使用国内镜像源 零.问题 使用pip安装插件时总是很慢,咋解决呢? 壹.解决 在桌面上你的文件夹内新建pip目录,一般路径如下:C:\Users\{$你的用户名},比如我的用户名是Minuy ...
- Hive SQL实现近N周的数据统计查询
文/朱季谦 先前遇到过一个需求,需要基于HIVE统计近N周范围的数据,例如,统计近7周范围的数据指标. 需要用HIVE SQL去实现该功能,而HIVE SQL并没有PostgreSQL那样例如通过函数 ...
- 《机器人SLAM导航核心技术与实战》先导课:课程大纲
<机器人SLAM导航核心技术与实战>先导课:课程大纲 视频讲解 [先导课]1.课程大纲-视频讲解 [先导课]1.1.课程大纲-学习思维导图(上)-视频讲解 [先导课]1.2.课程大纲-学习 ...
- 活动中台系统慢 SQL 治理实践
作者:vivo 互联网服务器团队- Zhang Mengtao 活动中台系统作为中台项目非常注重系统性能和用户体验,数据库系统性能问题会对应用程序的性能和用户体验产生负面影响.慢查询可能导致应用程序响 ...
- “你觉得客户需要”是杀死TA的最后一根稻草 | IPD集成产品开发
这个米老鼠洗衣机,大家眼熟吗? 相信最近热衷于在网上冲浪的朋友们,对这款形似米老鼠的"懒人洗衣机"并不陌生,甚至算是小小地参与了一下这个产品研发项目.在海尔的周云杰总裁爆火出圈后, ...
- freertos消息队列的值传递和指针传递
消息队列的使用方法总结: 1.消息队列初始化(定义一个消息队列的结构体),一般在main.c中完成. 2.消息队列的发送: a extern 消息队列 b 定义一个结构体的指针指向消息消息队列 ...
- HTTP表单请求
okHttp 发送表单请求 需要添加依赖 compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.9.0' import ...
- 使用CAMEL实现Graph RAG过程记录
前言 本文为学习官方文档Graph RAG Cookbook - CAMEL 0.2.47 documentation的学习记录. 配置Neo4j图数据库 第一步先配置 Neo4j 图数据库. 在浏览 ...
- 全局搜索——Lucene.Net与盘古分词的实现思路
一.Lucene.Net 1.Lucene.Net介绍: Lucene.Net是一个C#开发的开源全文索引库(自带的有索引管理.分词.查询) Lucene.Net.Index 提供索引管理,词组排序. ...