dyllalala

导航

[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 }
我的心已片片飘落

 

posted on 2014-11-15 09:54  dyllalala  阅读(355)  评论(0编辑  收藏  举报