首页 > 其他分享 >[CF1672G]Cross Xor

[CF1672G]Cross Xor

时间:2023-10-10 16:55:07浏览次数:40  
标签:CF1672G Xor int Cross 异或 权值 MOD

G - Cross Xor

对于\((n\&1)\&\&(m\&1)\)的情况,所有行、列的异或和的必须相等(异或和指当前行/列中所有元素的异或和)

  1. 每次修改的点\((x_1,y_1)\),\((x_2,y_1)\),\((x_1,y_2)\),\((x_2,y_2)\)使得所有行和列的异或和不会改变

  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,Xor,int,Cross,异或,权值,MOD
From: https://www.cnblogs.com/LuoyuSitfitw/p/17755128.html

相关文章

  • gym102331B Bitwise Xor
    gym102331BBitwiseXor和我找到的题解都不同的做法。感觉简单一些。首先将\(a\)排序,从高位往低位考虑,假设考虑第\(p\)位,不难发现这时序列按照第\(p\)位取值被划分为两部分,我们注意到如果\(x\)的这一位是\(0\)那么这两部分各取两个数异或起来一定满足限制,故两部分互互......
  • [CF1654F] Minimal String Xoration
    MinimalStringXoration有点智慧但不是特别智慧反正是我达不到的智慧。打表可以看出长度为\(2^x\)的\(i\oplusk\)出现次数为\(2^{n-k}\)。进一步发现,设\(f(k,x)\)当前选取k时,数列前\(2^k\)的下标。则\(f(k,x)=f(k,x-1)+f(k\oplus{2^{x-1}},x-1)\)因为对于\(......
  • 论文解读:CrossPoint: Self-Supervised Cross-Modal Contrastive Learning for 3D Poin
    CrossPoint:Self-SupervisedCross-ModalContrastiveLearningfor3DPointCloudUnderstanding本文提出一种简单的跨模态3维—2维区域对应模块,分别将点云模态和图像模态提取的特征向量重新投影到一个公共的特征空间中,并基于最大化与模态无关的互信息的思想设计对比学习损失......
  • CF1879D Sum of XOR Functions
    异或和按位处理的典型例题。要求所有子区间异或和乘区间长度的总和,朴素的方法是\(O(n^2)\)地枚举区间,显然无法通过。因为涉及异或和,而异或运算不进位,故自然地想到把\(a_i\)写成二进制形式,单独研究每一位的贡献,最后再合并。这是处理此类问题的一般思路。1.二进制拆分比方......
  • Xor
    [ABC098D]XorSum2常规做法:发现区间缩小后肯定还是满足要求,于是双指针即可。code1非常规做法:(我的做法)我们可以发现,如果没有任何一个\(0\),那么区间长度不超过\(20\)。如何克服\(0\)?我们每个位置向右维护第一个非零的位置,然后每次跳到非零位置累加,根据最远长度计算个数。......
  • @Crossorigin 跨域不起作用
    今天在做SpringBoot项目时发现@Crossorigin注解不起作用经过排查后发现是我的axios.get()方法中的url 写错了在此记录下@Crossorgin不生效的几种原因:1.请求不正确,如url写错,@RequestMapping等路径设置错误2.没有在@RequestMapping中设置method,指定提交方式如将@RequestMap......
  • Xor-Subsequence (字典树优化DP)
     思路;明显的是,后一个i要从前面一个进行更新, 利用dpeasy版本ai<=200,发现当n>=300时,对他是没有影响的,这样比较好记录ans进行更新,利用数据结构处理hard版本拆位,利用字典树dp,把参数变成相同的参数,a[i]和i,(比大小:前K位一样第K+1位不一样......
  • KingbaseES数据库改写SQL Server数据库CROSS APPLY和OUTER APPLY
    一、功能介绍:CROSSAPPLY和OUTERAPPLY是SQLServer中的一种连接操作,类似于JOIN语句可以将一张表与一个表函数或一个子查询进行关联。表函数是一种返回一个表类型的数据的函数,子查询是一个嵌套在外部查询中的查询。它们可以与表值函数或子查询配合使用,返回左表和右表的匹配结果。......
  • 软件测试|MySQL CROSS JOIN:交叉连接的详细解析
    简介在MySQL数据库中,CROSSJOIN是一种用于生成两个或多个表的笛卡尔积的连接方法。CROSSJOIN不需要任何连接条件,它将左表的每一行与右表的每一行进行组合,从而生成一个包含所有可能组合的结果集。本文将详细介绍MySQL中的CROSSJOIN概念,并提供示例来加深理解。什么是CROSS......
  • Xor
    moectf{You_kn0w_h0w_t0_X0R!}XOR下载直接得到一个exe程序拖入die,64位,无壳拖入idaF5得到重点在enc数组,然后input字符串要跟其进行亦或操作,所以只要找到enc数组再将其跟0x39进行亦或便可以得到input数组(a^b=c==a^c=b)但是这里的伪代码没有enc的定义,只能在汇编代码里寻......