[BZOJ 3503][Cqoi 2014]和谐矩阵
我觉得这一题的样例输出一点都不和谐,大家千万别像我一样被坑了……
题目不算难,果然是进错省系列555,不过搞出 O(n*m*2m) 的还是不要挣扎的比较好
我们暴力地推出第 n 行 第 m 列中每个数是第 1 行的哪些数的 nim 和 ——O(n3)
然后再算出 b[j] = a[n][j] xor a[n-1][j] xor a[n][j+1] xor a[n][j-1]
就有了一个似是而非的一个抑或方程组,因为如果去解的话结果一定是 xi=0
怎么办呢?
既然题目说一定有解,必然存在一个 xi=1 , 我们就暴力枚举!然后尝试解方程组即可 ——O(n4)
1 #include <cstdio> 2 #include <cstring> 3 const int sizeOfMatrix=42; 4 5 int m, n; 6 inline int getint(); 7 inline void putint(bool); 8 9 struct node 10 { 11 bool a[sizeOfMatrix]; 12 inline node() {memset(a, 0, sizeof(a));} 13 inline bool & operator [] (int x) {return a[x];} 14 }; 15 inline node operator ^ (node a, node b) 16 { 17 node c; 18 for (int i=1;i<=n;i++) c[i]=a[i]^b[i]; 19 return c; 20 } 21 22 node a[sizeOfMatrix][sizeOfMatrix]; 23 node f[sizeOfMatrix]; 24 bool b[sizeOfMatrix][sizeOfMatrix]; 25 bool x[sizeOfMatrix]; 26 inline void swap(bool & , bool & ); 27 inline bool solve(int); 28 inline bool calc(int, int); 29 30 int main() 31 { 32 m=getint(), n=getint(); 33 for (int i=1;i<=n;i++) a[1][i][i]=true; 34 for (int i=2;i<=m;i++) 35 for (int j=1;j<=n;j++) 36 a[i][j]=a[i-1][j]^a[i-1][j-1]^a[i-1][j+1]^a[i-2][j]; 37 for (int i=1;i<=n;i++) 38 f[i]=a[m][i]^a[m][i-1]^a[m][i+1]^a[m-1][i]; 39 40 for (int i=1;i<=n;i++) 41 if (solve(i)) 42 break; 43 44 for (int i=1;i<=m;i++) 45 { 46 for (int j=1;j<=n;j++) 47 putint(calc(i, j)); 48 putchar('\n'); 49 } 50 51 return 0; 52 } 53 inline int getint() 54 { 55 register int num=0; 56 register char ch; 57 do ch=getchar(); while (ch<'0' || ch>'9'); 58 do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9'); 59 return num; 60 } 61 inline void putint(bool num) 62 { 63 if (num) putchar('1'); 64 else putchar('0'); 65 putchar(' '); 66 } 67 inline void swap(bool & a, bool & b) 68 { 69 bool t=a; a=b; b=t; 70 } 71 inline bool solve(int k) 72 { 73 for (int i=1;i<=n;i++) 74 { 75 for (int j=1;j<=n;j++) 76 b[i][j]=f[i][j]; 77 if (f[i][k]==true) 78 b[i][k]=false, b[i][n+1]=true; 79 } 80 for (int i=1;i<=n;i++) 81 { 82 if (!b[i][i]) 83 { 84 for (int j=i+1;j<=n;j++) if (b[j][i]) 85 { 86 for (int k=1;k<=n+1;k++) 87 swap(b[j][k], b[i][k]); 88 break; 89 } 90 } 91 92 if (!b[i][i]) continue; 93 94 for (int j=i+1;j<=n;j++) if (b[j][i]) 95 for (int k=i;k<=n+1;k++) 96 b[j][k]^=b[i][k]; 97 } 98 99 x[k]=true; 100 for (int i=n;i>=1;i--) 101 { 102 if (!b[i][i]) continue; 103 x[i]=b[i][n+1]; 104 for (int j=n-1;j>=1;j--) if (b[j][i]) 105 b[j][i]=false, b[j][n+1]^=x[i]; 106 } 107 108 for (int i=1;i<=n;i++) 109 { 110 bool check=false; 111 for (int j=1;j<=n;j++) if (f[i][j]) 112 check^=x[j]; 113 if (check) return false; 114 } 115 116 return true; 117 } 118 inline bool calc(int i, int j) 119 { 120 bool ans=false; 121 for (int k=1;k<=n;k++) if (a[i][j][k]) 122 ans^=x[k]; 123 return ans; 124 }