[BZOJ 3503] [CQOI 2014] Harmony Matrix

f[i][j]=1 means that the position of I has an effect on the position of j, even number 1 means the number of influential numbers and 0 i n the case of modulus 2. This can list n*m equations and obtain a set of feasible solutions by Gauss elimination method.
There are two points to note: for convenience, exclusive or can be used instead of adding, because exclusive or also satisfies the exchange law and combination law. Also, if there are innumerable groups of solutions, priority is given to 1, because the answer can not be all 0.

#include<cmath>
#include<cstdio>
#include<vector>
#include <queue>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 2000
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
int i,j,k,n,m,tot;
int a[N][N],res[N],d[10][10],id[100][100];
void Gauss(int n,int m)
{
    int i,j,k;
    fo(i,1,n)
        {
            j = i; while (!a[j][i] && j <= m) j++;
            if (j > n) continue;
            if (j != i) fo(k,i,m) swap(a[i][k],a[j][k]);
            fo(j,i+1,n)
                if (a[j][i]) fo(k,i,m) a[j][k] ^= a[i][k];
        }
    fd(i,n,1)
        {
            if (!a[i][i]) {res[i] = 1; continue;}
            fo(j,i+1,n)
                a[i][m] ^= (res[j] * a[i][j]);
            res[i] = a[i][m]; 
        }
}

int main()
{
    d[1][0] = 0; d[1][1] = 0;
    d[2][0] = 1; d[2][1] = 0;
    d[3][0] = -1; d[3][1] = 0;
    d[4][0] = 0; d[4][1] = 1;
    d[5][0] = 0; d[5][1] = -1;
    scanf("%d%d",&n,&m);
    fo(i,1,n)
        fo(j,1,m)
            id[i][j] = ++tot;
    fo(i,1,n)
        fo(j,1,m)
            fo(k,1,5)
                {
                    int p = id[i+d[k][0]][j+d[k][1]];
                    if (p) a[id[i][j]][p] = 1;
                }
    Gauss(tot,tot+1);
    tot = 0;
    fo(i,1,n)
        {
            cout<<res[++tot];
            fo(j,2,m) cout<<" "<<res[++tot];
            cout<<endl;
        }
    return 0;   
}

extra

There is a quicker way to solve this problem, so we can see the conscience of the author.
We find that when the number of the first line is determined, the number of the next n-1 line can be determined by greed, and the problem now turns to how to find a set of feasible first lines.
The necessary and sufficient condition for the first line to be feasible is that the number of the last line satisfies the requirement (if the odd number of the first n-1 line can be adjusted by the latter line, and the last line can only satisfy itself), which is also equivalent to (assuming that the added) line n+1 is all zero.
Considering that all the questions can be done by XOR, the influence of the first line number on the number of lines n+1 is analyzed. The number of the first row is assigned 2^i, so that there is no effect between the m numbers. Then fill in the (n+1)*m lattices and observe which numbers in line n+1 are not zero, indicating the effect of some numbers in the first line on the number. Similarly, n equations are listed, and Gauss elimination is enough.

#include<cmath>
#include<cstdio>
#include<vector>
#include <queue>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 41
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
int n,m,i,j;
int a[N][N],res[N][N];
ll b[N][N];
void gauss()
{
    int i,j,k;
    fo(i,1,m)
        {
            j = i; while (!a[j][i] && j <= m) j++;
            if (j > m) continue;
            if (j != i) fo(k,i,m+1) swap(a[i][k],a[j][k]);
            fo(j,i+1,m)
                if (a[j][i]) fo(k,i,m+1) a[j][k] ^= a[i][k];
        }
    fd(i,m,1)
        {
            if (!a[i][i]) {res[1][i] = 1; continue;}
            fo(j,i+1,m)
                a[i][m+1] ^= (res[1][j] * a[i][j]);
            res[1][i] = a[i][m+1];
        }
}
int main()
{
    scanf("%d%d",&n,&m);
    fo(i,1,m) b[1][i] = (ll)1<<(i-1);
    fo(i,2,n+1)
        fo(j,1,m)
            b[i][j] =b[i-1][j-1] ^ b[i-1][j] ^ b[i-1][j+1] ^ b[i-2][j];
    fo(i,1,m)
        fo(j,1,m)
            a[i][j] = ((b[n+1][i])>>(j-1))&1;
    gauss();
    fo(i,1,m-1) printf("%d ",res[1][i]); printf("%d\n",res[1][m]);
    fo(i,2,n)
        {
            fo(j,1,m) res[i][j] =res[i-1][j-1] ^ res[i-1][j] ^ res[i-1][j+1] ^ res[i-2][j];
            fo(j,1,m-1) printf("%d ",res[i][j]); printf("%d\n",res[i][m]);
        }
    return 0;
}

Posted by dave_2008 on Thu, 18 Apr 2019 15:21:34 -0700