BZOJ3503: [Cqoi2014]和谐矩阵

题解:

如果第一行的数知道了,我们就可以推出其他行的数。

那么如何判断第一行的数的一种填法是否合法呢?很简单,我们递推出m+1行的数,当且仅当这一行都是0时满足题意。

那么,我们就有了一种想法。

直接把m+1行的每个数用x[1..n]表示出来,这一定是个系数只为0/1的式子。然后让这个异或值=0,就可以解异或方程组了。

系数怎么推呢?

for1(i,n)b[1][i]=(ll)1<<i-1;
    for2(i,2,m+1)
     for1(j,n)
      b[i][j]=b[i-1][j]^b[i-1][j-1]^b[i-1][j+1]^b[i-2][j];

然后解方程就可以了。

代码:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 50+5
14 #define maxm 100000+5
15 #define eps 1e-10
16 #define ll long long
17 #define pa pair<int,int>
18 #define for0(i,n) for(int i=0;i<=(n);i++)
19 #define for1(i,n) for(int i=1;i<=(n);i++)
20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
22 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
23 #define mod 1000000007
24 using namespace std;
25 inline int read()
26 {
27     int x=0,f=1;char ch=getchar();
28     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
29     while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}
30     return x*f;
31 }
32 int n,m;
33 ll a[maxn][maxn],b[maxn][maxn],c[maxn][maxn];
34 inline void gauss()
35 {
36     for1(i,n)
37     {
38         int k=i;
39         while(k<=n&&!a[k][i])k++;
40         if(k>n)continue;
41         for2(j,i,n+1)swap(a[i][j],a[k][j]);
42         for2(j,i+1,n)if(a[j][i])
43          for2(k,i,n+1)
44           a[j][k]^=a[i][k];
45     }
46     for3(i,n,1)
47     {
48         c[1][i]=a[i][n+1];
49         if(!a[i][i]){c[1][i]=1;continue;}
50         for2(j,i+1,n)if(a[i][j])c[1][i]^=c[1][j];
51     }
52 }
53 int main()
54 {
55     freopen("input.txt","r",stdin);
56     freopen("output.txt","w",stdout);
57     m=read();n=read();
58     for1(i,n)b[1][i]=(ll)1<<i-1;
59     for2(i,2,m+1)
60      for1(j,n)
61       b[i][j]=b[i-1][j]^b[i-1][j-1]^b[i-1][j+1]^b[i-2][j];
62     for1(i,n)
63      for1(j,n)
64       a[i][j]=b[m+1][i]>>(j-1)&1;
65     gauss();
66     for2(i,2,m)
67      for1(j,n)
68       c[i][j]=c[i-1][j]^c[i-1][j-1]^c[i-1][j+1]^c[i-2][j];
69     for1(i,m){for1(j,n-1)printf("%d ",c[i][j]);printf("%d\n",c[i][n]);}
70     return 0;
71 }

时间: 2024-11-03 03:30:20

BZOJ3503: [Cqoi2014]和谐矩阵的相关文章

【高斯消元】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]和谐矩阵

3503: [Cqoi2014]和谐矩阵 Time Limit: 10 Sec Memory Limit: 128 MBSec Special Judge Submit: 493 Solved: 216 [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

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

传送门 题意:给出$N,M$,试构造一个$N \times M$的非全$0$矩阵,其中所有格子都满足:它和它上下左右四个格子的权值之和为偶数.$N , M \leq 40$ 可以依据题目中的条件列出有$N \times M$的元.$N \times M$个方程的异或方程组(异或方程组就是所有位置都是$1$或$0$,最右边一列的答案需要通过异或互相消除的方程组,一般在$mod\,2$意义下产生). 理论上元和方程组数量一致的时候每一个元都是有唯一解的,但是在有解的情况下,其中一些方程是线性相关的,

【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

【BZOJ】【3503】【CQOI2014】和谐矩阵

高斯消元解Xor方程组 Orz ZYF o(︶︿︶)o 唉我的数学太烂了…… 错误思路:对每个格点进行标号,然后根据某5个异或和为0列方程组,高斯消元找自由元……(目测N^3会TLE) ZYF的正确思路: 如果第一行的数知道了,我们就可以推出其他行的数. 那么如何判断第一行的数的一种填法是否合法呢?很简单,我们递推出m+1行的数,当且仅当这一行都是0时满足题意. 那么,我们就有了一种想法. 直接把m+1行的每个数用x[1..n]表示出来,这一定是个系数只为0/1的式子.然后让这个异或值=0,就可

解题:CQOI 2013 和谐矩阵

题面 踩踩时间复杂度不正确的高斯消元 首先可以发现第一行确定后就可以确定整个矩阵,所以可以枚举第一行的所有状态然后$O(n)$递推检查是否合法 $O(n)$递推的方法是这样的:设$pre$为上一行,$now$为当前行,$nxt$为递推出的下一行,$all$为列的全集,则可以直接用位运算完成递推: $nxt=all\&((now<<1)xor(now>>1)xor$ $now$ $xor$ $pre)$ 递推后第$n+1$行为空则说明可行 问题来了,第一行的状态有$O(2^{

BZOJ 3503 CQOI 2014 和谐矩阵 高斯消元

题目大意:给出m和n,求出一种方案使得每一个点和周围的四个点的1的个数为偶数. 思路:根据题意可以列出m*n个异或方程,然后组成异或方程组.解这个异或方程组然后输出任意一个解就可以了. PS:值得注意的是,全是0肯定是一个解,显然你不能输出这个解.所以你需要让一个或一些自由元的值为1,至于怎么做,随便yy就行了. PS2:这个题的样例吞掉了空格,然而又是SPJ,所以就是wa..然后我wa了一下午.. CODE: #include <cstdio> #include <cstring>

Bzoj3503--Cqoi2014和谐矩阵

原本想每个点建个五元异或方程组高斯消元解的,发现时间有点紧,就去压位卡常,结果调试的时候把自己挂在键盘上了.- -| 正解是从第一排推出第m+1排的异或表达式,然后因为m+1排的数全为0,转回来解这个异或方程组. 实现上我是消的对角线,消成上三角可能会快.出于习惯,我是把n,m互换了的. 代码: #include<bits/stdc++.h> #define INF 1000000000 #define LNF 100000000000000ll #define eps 1e-9 #defin