Luogu3164 CQOI2014 和谐矩阵 异或、高斯消元

传送门

题意:给出$N,M$,试构造一个$N \times M$的非全$0$矩阵,其中所有格子都满足:它和它上下左右四个格子的权值之和为偶数。$N , M \leq 40$



可以依据题目中的条件列出有$N \times M$的元、$N \times M$个方程的异或方程组(异或方程组就是所有位置都是$1$或$0$,最右边一列的答案需要通过异或互相消除的方程组,一般在$mod\,2$意义下产生)。

理论上元和方程组数量一致的时候每一个元都是有唯一解的,但是在有解的情况下,其中一些方程是线性相关的,这意味着消到最后,某一些行会变成全$0$(如果不是很清楚可以像$vegetable chicken$我一样打一波$3 \times 3$和$4 \times 4$的表)。我们可以把行全$0$的元(又称之为自由元)全部设为$1$,因为它们是多少对方程最后有无解没有关系,然后一步步把上面推出来即可。

因为复杂度为$1600^3$平常的高斯消元速度很慢,所以可以用神仙$STL\,bitset$优化

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3
 4 inline int read(){
 5     int a = 0;
 6     bool f = 0;
 7     char c = getchar();
 8     while(c != EOF && !isdigit(c)){
 9         if(c == ‘-‘)
10             f = 1;
11         c = getchar();
12     }
13     while(c != EOF && isdigit(c)){
14         a = (a << 3) + (a << 1) + (c ^ ‘0‘);
15         c = getchar();
16     }
17     return f ? -a : a;
18 }
19
20 const int dir[5][2] = {0,1,0,-1,1,0,-1,0,0,0};
21 bitset < 1600 > gauss[1600] , ans;
22
23 int main(){
24 #ifdef LG
25     freopen("3164.in" , "r" , stdin);
26     freopen("3164.out" , "w" , stdout);
27 #endif
28     int M , N;
29     cin >> M >> N;
30     for(int i = 0 ; i < M ; i++)
31         for(int j = 0 ; j < N ; j++)
32             for(int k = 0 ; k < 5 ; k++)
33                 if(i + dir[k][0] >= 0 && i + dir[k][0] < M && j + dir[k][1] >= 0 && j + dir[k][1] < N)
34                     gauss[i * N + j][(i + dir[k][0]) * N + j + dir[k][1]] = 1;
35     int now = 0;
36     for(int i = 0 ; i < M * N ; i++){
37         int j = now;
38         while(j < M * N && !gauss[j][i])
39             j++;
40         if(j == M * N)
41             continue;
42         if(j != now)
43             swap(gauss[now] , gauss[j]);
44         while(++j < M * N)
45             if(gauss[j][i])
46                 gauss[j] ^= gauss[now];
47         now++;
48     }
49     for(int i = M * N - 1 ; i >= 0 ; i--){
50         if(!gauss[i][i])
51             ans[i] = 1;
52         if(ans[i])
53             for(int j = i - 1 ; j >= 0 ; j--)
54                 if(gauss[j][i])
55                     ans[j] = ans[j] ^ 1;
56     }
57     for(int i = 0 ; i < M ; i++){
58         for(int j = 0 ; j < N ; j++){
59             putchar(ans[i * N + j] + 48);
60             putchar(‘ ‘);
61         }
62         putchar(‘\n‘);
63     }
64     return 0;
65 }

原文地址:https://www.cnblogs.com/Itst/p/9865061.html

时间: 2024-10-15 11:26:28

Luogu3164 CQOI2014 和谐矩阵 异或、高斯消元的相关文章

POJ 1222【异或高斯消元|二进制状态枚举】

题目链接:[http://poj.org/problem?id=1222] 题意:Light Out,给出一个5 * 6的0,1矩阵,0表示灯熄灭,反之为灯亮.输出一种方案,使得所有的等都被熄灭. 题解:首先可以用高斯消元来做,对于每个点,我们列出一个方程,左边是某个点和它相邻的点,他们的异或值等于右边的值(灯亮为1 ,灯灭为0),然后求一个异或高斯消元就可以了.可以用bitset优化,或者__int128优化(其实unsigned就可以了). 还可以枚举第一行的按开关的状态共有1<<6中状态

[spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)

In some countries building highways takes a lot of time... Maybe that's because there are many possiblities to construct a network of highways and engineers can't make up their minds which one to choose. Suppose we have a list of cities that can be c

P3317 [SDOI2014]重建 变元矩阵树定理 高斯消元

传送门:https://www.luogu.org/problemnew/show/P3317 这道题的推导公式还是比较好理解的,但是由于这个矩阵是小数的,要注意高斯消元方法的使用: #include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include

BZOJ.1923.[SDOI2010]外星千足虫(高斯消元 异或方程组 bitset)

题目链接 m个方程,n个未知量,求解异或方程组. 复杂度比较高,需要借助bitset压位. 感觉自己以前写的(异或)高斯消元是假的..而且黄学长的写法都不需要回代. //1100kb 324ms #include <cstdio> #include <cctype> #include <bitset> #include <algorithm> const int N=1004,M=2004; int n,m; char s[N]; std::bitset&l

线性空间和异或空间(线性基)bzoj4004贪心+高斯消元

线性空间:是由一组基底构成的所有可以组成的向量空间 对于一个n*m的矩阵,高斯消元后的i个主元可以构成i维的线性空间,i就是矩阵的秩 并且这i个主元线性无关 /* 每个向量有权值,求最小权极大线性无关组 本题是使用贪心策略的高斯消元 由输入给出的n个物品,每个物品有m种属性,和价格price 如果a物品的属性可以由其他已有物品的属性组合出,那么a可以不必购买 问最少花掉多少钱,使得所有物品都可以组合出 首先构建n*m矩阵,然后高斯消元 在求第i个主元时,取价格最小的那个即可 可用反证法证明 */

bzoj 1923: [Sdoi2010]外星千足虫【高斯消元】

裸的异或高斯消元 #include<iostream> #include<cstdio> using namespace std; const int N=2005; int n,m,a[N][N],ans; char s[N]; void gaosi() { for(int i=1;i<=n;i++) { int nw=i; while(!a[nw][i]&&nw<=m) nw++; if(nw==m+1) { ans=-1; return; } an

【BZOJ3503】【Cqoi2014】和谐矩阵 高斯消元,解异或方程组

#include <stdio.h> int main() { puts("转载请注明出处"); puts("地址:blog.csdn.net/vmurder/article/details/43699831"); } 题解: 随便搞搞就好. 自由元全当成1就好了么~~~ 不会异或方程组的移步这里[POJ1222]EXTENDED LIGHTS OUT 高斯消元.解异或方程组 代码: #include <cstdio> #include &l

【高斯消元】BZOJ3503 [Cqoi2014]和谐矩阵

3503: [Cqoi2014]和谐矩阵 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1197  Solved: 570[Submit][Status][Discuss] Description 我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本 身,及他上下左右的4个元素(如果存在). 给定矩阵的行数和列数,请计算并输出一个和谐的矩阵.注意:所有元素为0的矩

BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元

题意: 我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1.一个元素相邻的元素包括它本身,及他上下左右的4个元素(如果存在).给定矩阵的行数和列数,请计算并输出一个和谐的矩阵.注意:所有元素为0的矩阵是不允许的. 分析: 考虑一种暴力,设n*m个未知数,列n*m个方程 高斯消元解方程,注意全零矩阵不合法 那我们如果发现有自由元就将它们置为1 代码: #include <stdio.h> #include <string.h> #include <algo