为什么可以跑n立方,我也不知道,反正就是可以。

模2意义的,据说每一行可以存一个bitset,会比用bool更快(快32倍?)。

本题告诉我们一个道理:

高斯消元之后,每个变量的含义不变(虽然交换了两行,但是实际上那个位置的向量还是表示那个单元),不需要复原。

每个变量要前往的目标状态不一样。注意非自由变量要用新的右边来确定值。

并不是所有的自由变量都在右下角,有可能有完全空的列。

也可以在给每行赋值秩的同时指定该列是秩为第几的列,0表示空列。

可以在消元的同时对自由变量进行赋值,非自由变量立刻由他决定。但是感觉很扯。

#include<bits/stdc++.h>
#define ll long long
using namespace std; int n,m,r; inline int antii(int id) {
int res=((id+m-1)/m);
return res;
} inline int antij(int id) {
int res=id%m;
if(res==0)
res=m;
return res;
} inline int id(int,int); bool tx[1800]= {};
bool allzero[1800]= {};
bool outtm[50][50]= {}; bool out() {
int have1=0;
for(int id=1; id<=n*m; id++) {
outtm[antii(id)][antij(id)]=tx[id];
} for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
if(outtm[i][j]^outtm[i-1][j]^outtm[i+1][j]^outtm[i][j-1]^outtm[i][j+1]) {
return false;
}
if(outtm[i][j])
have1=1;
}
} if(!have1)
return false; for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++)
printf("%d%c",(int)outtm[i][j]," \n"[j==m]);
} return true; //高斯消元后,每个变量的目标已经改变了,不需要复原!!!
} namespace Gauss_Jordan_Elimination {
const int MAXN=1800;
const int MAXM=1800;
bool a[MAXN][MAXM+1];
bool ans[MAXN]; //返回增广矩阵的秩,-1表示无解
int gauss_jordan(int n,int m) { int r=0;
for(int i=1; i<=m; i++) {
//当前是第i列
int mx=-1;
//从当前秩的下一行开始往下数
for(int j=r+1; j<=n; j++)
if(a[j][i]) {
mx=j;
break;
}
if(mx==-1) {
//该列全0,被跳过
continue;
}
r++;
//增加一个线性基,当前秩增加
if(mx!=r) {
//需要交换
for(int j=1; j<=m+1; j++)
//m+1表示增广矩阵
swap(a[r][j],a[mx][j]);
//交换行
} for(int j=1; j<=n; j++) {
//枚举每一行
if(j!=r&&a[j][i]) {
//消去除了r以外的其他行
//该行系数是当前列的tmp倍
for(int k=i; k<=m+1; k++) {
//把当前列对应行位置扩大tmp倍,然后用每个元素减去,由高斯约当的过程,左边的绝对是0
a[j][k]^=a[r][k];
}
}
}
} return r;
}
} using namespace Gauss_Jordan_Elimination; inline int id(int i,int j) {
if(i>=1&&i<=n&&j>=1&&j<=m)
return (i-1)*m+j;
else
return 0;
} int dx[4]= {-1,1,0,0};
int dy[4]= {0,0,-1,1}; void dfs(int x,bool have1) {
if(x==0) {
if(have1) {
if(out()) {
exit(0);
}
}
return;
}
if(allzero[x]) {
tx[x]=1;
dfs(x-1,1);
tx[x]=0;
dfs(x-1,have1);
} else {
bool v=a[x][n*m+1];
for(int i=x+1; i<=n*m; i++) {
v^=a[x][i]&tx[i];
}
tx[x]=v;
dfs(x-1,have1|v);
}
} int main() {
scanf("%d%d",&n,&m); {
{
memset(a,0,sizeof(a));
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
int tid=id(i,j);
a[tid][tid]=1;
for(int k=0; k<4; k++) {
int ttid=id(i+dx[k],j+dy[k]);
if(ttid) {
a[tid][ttid]=1;
}
}
}
} r=gauss_jordan(n*m,n*m); for(int i=1; i<=n*m; i++) {
allzero[i]=1;
for(int j=1; j<=n*m; j++) {
if(a[i][j]) {
allzero[i]=0;
break;
}
}
} dfs(n*m,0);
}
} }

洛谷 - P3164 - 和谐矩阵 - 高斯约旦消元法的更多相关文章

  1. BZOJ 3503: [Cqoi2014]和谐矩阵( 高斯消元 )

    偶数个相邻, 以n*m个点为变量, 建立异或方程组然后高斯消元... O((n*m)^3)复杂度看起来好像有点大...但是压一下位的话就是O((n*m)^3 / 64), 常数小, 实际也跑得很快. ...

  2. 【bzoj3240 && 洛谷P1397】矩阵游戏[NOI2013](矩阵乘法+卡常)

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3240 这道题其实有普通快速幂+费马小定理的解法……然而我太弱了,一开始只想到了矩阵乘法的 ...

  3. BZOJ1059或洛谷1129 [ZJOI2007]矩阵游戏

    BZOJ原题链接 洛谷原题链接 通过手算几组例子后,很容易发现,同一列的\(1\)永远在这一列,且这些\(1\)有且仅有一个能产生贡献,行同理. 所以我们可以只考虑交换列,使得每一行都能匹配一个\(1 ...

  4. 洛谷P3164 [CQOI2014]和谐矩阵

    高斯消元,可以直接消的 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cst ...

  5. P3164 [CQOI2014]和谐矩阵(高斯消元 + bitset)

    题意:构造一个$n*m$矩阵 使得每个元素和上下左右的xor值=0 题解:设第一行的每个元素值为未知数 可以依次得到每一行的值 然后把最后一行由题意条件 得到$m$个方程 高斯消元解一下 bitset ...

  6. BZOJ3503:[CQOI2014]和谐矩阵(高斯消元,bitset)

    Description 我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本 身,及他上下左右的4个元素(如果存在). 给定矩阵的行数和列数,请计算并输 ...

  7. 洛谷P1397 [NOI2013]矩阵游戏

    矩阵快速幂+费马小定理 矩阵也是可以跑费马小定理的,但是要注意这个: (图是盗来的QAQ) 就是说如果矩阵a[i][i]都是相等的,那么就是mod p 而不是mod p-1了 #include< ...

  8. 【洛谷P1129】矩阵游戏

    题目大意:给定一个 N*N 的矩阵,有些格子是 1,其他格子是 0.现在允许交换若干次行和若干次列,求是否可能使得矩阵的主对角线上所有的数字都是1. 题解:首先发现,交换行和交换列之间是相互独立的.主 ...

  9. 洛谷 P1129 [ZJOI2007]矩阵游戏 解题报告

    P1129 [ZJOI2007]矩阵游戏 题目描述 小\(Q\)是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个\(N*N\)黑白方阵进行(如同国际象棋一般 ...

随机推荐

  1. asyncio协程与并发

    并发编程 Python的并发实现有三种方法. 多线程 多进程 协程(生成器) 基本概念 串行:同时只能执行单个任务 并行:同时执行多个任务 在Python中,虽然严格说来多线程与协程都是串行的,但其效 ...

  2. C++ 中的几种初始化

    前言 阅读C++教材时,想必你听过复制初始化,直接初始化,值初始化这三个概念吧.笔者本人常将其混淆,遂在此记录下它们的具体含义以便日后查阅. 复制初始化( copy-initialization ) ...

  3. IOS UIScrollView滚动到指定位置

    [mScrollView setContentOffset:CGPointMake(0,200) animated:YES];

  4. Windows8-x64 VMWare安装Linux CentOS6-x64

    本文參考了:http://www.cnblogs.com/seesea125/archive/2012/02/25/2368255.html 其内容相当具体,以至于我还没依照其步骤做完.系统就已经安装 ...

  5. iOS开发教程:Storyboard全解析-第一部分

    本文转载至http://blog.csdn.net/chang6520/article/details/7945845 感谢原文作者分享     故事版(Storyboard)是一个能够节省你很多设计 ...

  6. Requires: libstdc++.so.6(GLIBCXX_3.4.15)(64bit)

    Error: Package: mysql-community-server-8.0.12-1.el7.x86_64 (mysql80-community) Requires: libstdc++.s ...

  7. Recurrent neural networks are very powerful, because they combine two properties

    https://www.cs.toronto.edu/~hinton/csc2535/notes/lec10new.pdf Distributed hidden state that allows t ...

  8. ABAP 日期栏函数

    在SZC这个中有很多日期函数可以研究借鉴   ABAP - 日期格式转换 现在提供以下一些日期格式转换的函数: Below are several FMs which can be used to c ...

  9. 【操作系统】使用BCD工具安装Ubuntu操作系统

    Ubuntu14.04作为目前最新版本的ubuntu系统,相信很多人都想在自己的电脑上安装一下,然而系统的安装方法各式各样,U盘法.grub引导法等等,本文将介绍在win7系统下用easyBCD软件建 ...

  10. 数据结构之 图论---最小生成树(prim + kruskal)

    图结构练习——最小生成树 Time Limit: 1000MS Memory limit: 65536K 题目描述  有n个城市,其中有些城市之间可以修建公路,修建不同的公路费用是不同的.现在我们想知 ...