洛谷 - P3164 - 和谐矩阵 - 高斯约旦消元法
为什么可以跑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 - 和谐矩阵 - 高斯约旦消元法的更多相关文章
- BZOJ 3503: [Cqoi2014]和谐矩阵( 高斯消元 )
偶数个相邻, 以n*m个点为变量, 建立异或方程组然后高斯消元... O((n*m)^3)复杂度看起来好像有点大...但是压一下位的话就是O((n*m)^3 / 64), 常数小, 实际也跑得很快. ...
- 【bzoj3240 && 洛谷P1397】矩阵游戏[NOI2013](矩阵乘法+卡常)
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3240 这道题其实有普通快速幂+费马小定理的解法……然而我太弱了,一开始只想到了矩阵乘法的 ...
- BZOJ1059或洛谷1129 [ZJOI2007]矩阵游戏
BZOJ原题链接 洛谷原题链接 通过手算几组例子后,很容易发现,同一列的\(1\)永远在这一列,且这些\(1\)有且仅有一个能产生贡献,行同理. 所以我们可以只考虑交换列,使得每一行都能匹配一个\(1 ...
- 洛谷P3164 [CQOI2014]和谐矩阵
高斯消元,可以直接消的 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cst ...
- P3164 [CQOI2014]和谐矩阵(高斯消元 + bitset)
题意:构造一个$n*m$矩阵 使得每个元素和上下左右的xor值=0 题解:设第一行的每个元素值为未知数 可以依次得到每一行的值 然后把最后一行由题意条件 得到$m$个方程 高斯消元解一下 bitset ...
- BZOJ3503:[CQOI2014]和谐矩阵(高斯消元,bitset)
Description 我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本 身,及他上下左右的4个元素(如果存在). 给定矩阵的行数和列数,请计算并输 ...
- 洛谷P1397 [NOI2013]矩阵游戏
矩阵快速幂+费马小定理 矩阵也是可以跑费马小定理的,但是要注意这个: (图是盗来的QAQ) 就是说如果矩阵a[i][i]都是相等的,那么就是mod p 而不是mod p-1了 #include< ...
- 【洛谷P1129】矩阵游戏
题目大意:给定一个 N*N 的矩阵,有些格子是 1,其他格子是 0.现在允许交换若干次行和若干次列,求是否可能使得矩阵的主对角线上所有的数字都是1. 题解:首先发现,交换行和交换列之间是相互独立的.主 ...
- 洛谷 P1129 [ZJOI2007]矩阵游戏 解题报告
P1129 [ZJOI2007]矩阵游戏 题目描述 小\(Q\)是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个\(N*N\)黑白方阵进行(如同国际象棋一般 ...
随机推荐
- linux 块设备驱动(二)——块设备数据结构
本文来源于: 1. http://www.cnblogs.com/dyllove98/archive/2013/07/01/3165567.html 块设备相关的数据结构以及接口: 块设备接口则相对复 ...
- php 批量删除数据
php 批量删除数据 :比如我们在看邮箱文件的时候,积攒了一段时间以后,看到有些文件没有用了 这时候我们就会想到把这些 没用的文件删除,这时候就用到了批量删除数据的功能,这里我是用了数据库原有的一个表 ...
- ASP.NET MVC EXTJS 通用主菜单框架
一.说明 首先我不知道定义的文章标题是不是准确,我这篇博文介绍的是一个通用的软件主菜单框架,界面布局用的是extjs,还是先上一个图吧. 软件主界面左侧菜单采用的风格是extjs的手风琴模式,需要注意 ...
- c++的运算符的重载
1 什么是c++运算符的重载 c++运算符的重载就是说对+.-.>.<等运算符进行重新定义,这样的话,除了基本的类型,所有的类都可以进行基本的运算了,用起来非常方便.特别是用在各种算法中. ...
- linux SVN 安装配置
svn服务器有2种运行方式 1.独立服务器 (例如:svn://xxx.com/xxx):2.借助apache.(例如:http://svn.xxx.com/xxx):为了不依赖apache,选择第一 ...
- ckeditor html标签的class 等attribute属性都被屏蔽啦,替换成空的解决方案
ckeditor 模块中自定义class 在ckeditor模块中,编辑内容时, 在源码中填写<div class="myclass">some content< ...
- 【WordSearch】Word Search
Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...
- Python使用setuptools打包源文件(精简)
目录结构: F:\capt>tree ├─abc_test │ ├─__init__.py │ ├─comman_line.py ├─setup.py #__init.py__ def he ...
- Microsoft.AspNetCore.Identity 使用 mysql 报错处理
1.使用mysql 首先要确定mysql connector 支的版本,正面是链接 https://dev.mysql.com/doc/connector-net/en/connector-net-e ...
- [FJOI 2016] 神秘数
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4408 [算法] 首先考虑一组询问怎样做 : 将数组按升序排序 , 假设我们现在可以表 ...