• 解题: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
  • 相关阅读:
    随笔:金融的“游戏”规则——游戏世界的区块链喵与现实世界的金融科技
    js实现链表
    事件
    JQ操作DOM
    JQuery选择器
    AJAX
    file
    表单
    DOM
    window&navigator&screen&location
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9737308.html
Copyright © 2020-2023  润新知