zoukankan      html  css  js  c++  java
  • 633E Binary Table

    传送门

    分析

    我们发现n特别小,所以可以从这里入手

    我们记录出所有列中某一种状态的列有多少个

    我们再记录出每种列最少有多少个1(原来的1的个数和取反后的个数去最小值)

    于是我们可以得出对于所有列异或一个数的答案

    (实际就是对于每一行有一个全异或1或不异或的操作,将所有行压起来)

    于是我们不难得到式子$Ans_i = sum a_j * b_{j^i}$

    直接fwt即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define int long long
    string s[25];
    int a[2000000],b[2000000],n,m,N;
    inline void fwt(int a[],int f){
        int i,j,k;
        for(i=1;i<N;i<<=1)
          for(j=0;j<N;j+=(i<<1))
            for(k=0;k<i;k++){
              int x=a[j+k],y=a[i+j+k];
              a[j+k]=x+y,a[i+j+k]=x-y;
              if(f==-1)a[j+k]/=2,a[i+j+k]/=2;
            }
    }
    signed main(){
        int i,j,k;
        scanf("%lld%lld",&n,&m);
        N=(1<<n);
        for(i=1;i<=n;i++)cin>>s[i];
        for(i=0;i<m;i++){
          k=0;
          for(j=1;j<=n;j++)k=(k<<1)+(s[j][i]-'0');
          a[k]++;
        }
        for(i=1;i<N;i++)b[i]=b[i>>1]+(i&1);
        for(i=0;i<N;i++)b[i]=min(b[i],n-b[i]);
        fwt(a,1),fwt(b,1);
        for(i=0;i<N;i++)a[i]=a[i]*b[i];
        fwt(a,-1);
        int Ans=1e9+7;
        for(i=0;i<N;i++)Ans=min(Ans,a[i]);
        cout<<Ans;
        return 0;
    }
  • 相关阅读:
    Visio2019专业版激活方法
    I2C总线协议
    latch-up和Antenna-effect
    读--数字集成电路物理设计
    数字IC设计流程与工具
    读--FPGA设计指导原则
    读--数字集成电路设计与实现
    FIFO
    半导体存储器
    触发器
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10507869.html
Copyright © 2011-2022 走看看