• 2020 CCPC Wannafly Winter Camp Day5 J Xor on Figures(矩阵转01串,统计01串异或种类)


    题:https://ac.nowcoder.com/acm/contest/4120/J

    题意:一个初始全0矩阵M,给定一个相同大小的01矩阵F,允许操作为选择M中某一个位置放入F,然后M=M xor F 若超出范围则按题目那样转移;

       你可以用任意次操作,问所有操作所有能生成的最后的M的种类;

    分析:其实这题不难,关键是能保持清晰看完的心态;

       给定的矩阵大小很小,可以直接枚举每个位置放入F,再转化为01串,看最后的M能由哪些异或出来;

       其实就是“给定一些数,问最后能异或出来多少个数”,这就是线性基的绝活,长度太长,用bitset来处理

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    const int mod=1e9+7;
    const int N=1100;
    char s[N][N];
    bitset<N>p[N],a[N];
    int T,k;
    struct LB{
        void Insert(bitset<N> x){
            for(int i=T*T;i>=1;i--){
                if(x[i]){
                    if(p[i].count()>=1) x^=p[i];
    
                    else{
                        for(int j=0;j<=i-1;j++) if(x[j]) x^=p[j];
                        for(int j=i+1;j<=T*T;j++) if(p[j][i]) p[j]^=x;
                        p[i]=x;
                        return ;
                    }
                }
            }
        }
        ll getvec(){
            ll res=0;
            for(int i=1;i<=T*T;i++)
                if(p[i].count()>=1) res++;
            return res;
        }
    }lb;
    ll ksm(ll x,ll y){
        ll t=1ll;
        while(y){
            if(y&1)
                    t=t*x%mod;
            y>>=1;
            x=x*x%mod;
        }
        return t;
    }
    int main(){
        scanf("%d",&k);
        T=1<<k;
        for(int i=1;i<=T;i++)
            scanf("%s",s[i]+1);
        auto getid = [&](int x,int y){
            return (x-1)*T+y;
        };
        for(int x=1;x<=T;x++)///枚举(x,y)作为F的左上角起点
            for(int y=1;y<=T;y++){
                int u=getid(x,y);
                for(int i=1;i<=T;i++)///枚举(i,j)看F上这个位置是否为1,构建01串
                    for(int j=1;j<=T;j++){
                        if(s[i][j]=='1'){
                            a[u][getid( (x+i-1)%T+1 , (y+j-1)%T+1 )]=1;
                            ///printf("%d %d
    ",u,getid( (x+i-1)%T+1 , (y+j-1)%T+1 ));
                        }
    
                    }
            }
        for(int i=1;i<=T*T;i++){
            lb.Insert(a[i]);
        }
        ///异或和的种类可以通过线性基来求
        printf("%lld
    ",ksm(2ll,lb.getvec()));
        return 0;
    }
    View Code
  • 相关阅读:
    video和audio
    表单
    二叉树的先序遍历,后序遍历究竟是如何与快速排序,归并排序扯上关系?
    Python3下约瑟夫环的不同实现方式
    Golang下基于uint32的BitMap类库
    annotation
    流媒体技术
    C++系列之new 和 delete 的使用
    简易科学计算器的设计
    学生成绩档案管理系统的设计
  • 原文地址:https://www.cnblogs.com/starve/p/13866403.html
Copyright © 2020-2023  润新知