Bzoj3503--Cqoi2014和谐矩阵

原本想每个点建个五元异或方程组高斯消元解的,发现时间有点紧,就去压位卡常,结果调试的时候把自己挂在键盘上了。- -|

正解是从第一排推出第m+1排的异或表达式,然后因为m+1排的数全为0,转回来解这个异或方程组。

实现上我是消的对角线,消成上三角可能会快。出于习惯,我是把n,m互换了的。

代码:

#include<bits/stdc++.h>
#define INF 1000000000
#define LNF 100000000000000ll
#define eps 1e-9
#define LL long long
#define MOD 1000000007
inline int _max(int a,int b) {return a>b?a:b;}
inline double _fabs(double a) {return a>0?a:-a;}

using namespace std;
#define MAXN 45
#define MAXM 1605

LL xr[MAXN][MAXN],gs[MAXN];
int m,n,num[MAXN],mp[MAXN][MAXN];

void Gauss() {
    int p,now=1;
    for(int i=1;i<=m;i++) {
        p=now;
        while(p<=m&&!(gs[p]>>i&1)) p++;
        if(p>m) continue;
        swap(gs[p],gs[i]);swap(num[p],num[i]);
        for(int j=1;j<=m;j++) if(i!=j&&gs[j]>>i&1)
            gs[j]^=gs[i];
        now++;
    }
    p=m;
    for(int i=m;i;i--) {
        if(!(gs[i]>>i&1)) {mp[1][i]=1;continue;}
        for(int j=i+1;j<=m;j++) if(gs[i]>>j&1) mp[1][i]^=mp[1][j];
    }
    for(int i=2;i<=n;i++)
        for(int j=1;j<=m;j++)
            mp[i][j]=mp[i-1][j]^mp[i-1][j-1]^mp[i-1][j+1]^mp[i-2][j];
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) xr[1][i]=1ll<<i;
    for(int i=2;i<=n+1;i++)
        for(int j=1;j<=m;j++)
            xr[i][j]^=xr[i-1][j]^xr[i-1][j-1]^xr[i-1][j+1]^xr[i-2][j];
    for(int i=1;i<=m;i++) gs[i]=xr[n+1][i],num[i]=i;
    Gauss();
    for(int i=1;i<=n;i++) {
        printf("%d",mp[i][1]);
        for(int j=2;j<=m;j++) printf(" %d",mp[i][j]);
        printf("\n");
    }
    return 0;
}
时间: 2024-11-05 04:48:49

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的矩

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-

【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>