解题:CQOI 2013 和谐矩阵

Posted ydnhaha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解题: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^{40})$种,会$T$。但是有一个鬼畜的性质是如果存在合法解一定有一个对称的合法解,然后就可以$O(n*2^{frac{n}{2}})$出解了=。=

技术分享图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=50;
 6 int mapp[N][N];
 7 long long n,m,mid,all,half;
 8 long long fir,las,noww,tmp;
 9 int check(int a,int b)
10 {
11     return mapp[a][b]^mapp[a-1][b]^mapp[a][b-1]^mapp[a][b+1];
12 }
13 int main ()
14 {
15     scanf("%lld%lld",&n,&m);
16     mid=(m+1)/2,all=(1ll<<m)-1,half=(1ll<<mid)-1;
17     for(int i=1;i<=half;i++)
18     {
19         fir=0;
20         for(int j=1;j<=mid;j++)
21             if(i&(1ll<<(j-1))) fir|=(1ll<<(j-1))|(1ll<<(m-j));
22         las=noww=all&(fir^(fir<<1)^(fir>>1)),tmp=fir;
23         for(int j=2;j<=n;j++)
24             las=noww,noww=all&(noww^(noww<<1)^(noww>>1)^tmp),tmp=las;
25         if(!noww) break;
26     }
27     for(int i=1;i<=m;i++)
28         mapp[1][i]=(fir&(1ll<<(i-1)))?1:0;
29     for(int i=2;i<=n;i++)
30         for(int j=1;j<=m;j++)
31             mapp[i][j]=check(i-1,j);
32     for(int i=1;i<=n;i++)
33     {
34         for(int j=1;j<=m;j++)
35             printf("%d ",mapp[i][j]);
36         printf("
");
37     }
38     return 0;
39 }
View Code

 

以上是关于解题:CQOI 2013 和谐矩阵的主要内容,如果未能解决你的问题,请参考以下文章

高斯消元BZOJ3503 [Cqoi2014]和谐矩阵

BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元

P3164 [CQOI2014]和谐矩阵

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

解题:CQOI 2017 小Q的棋盘

CQOI2008矩阵的个数