zoukankan      html  css  js  c++  java
  • 矩阵

    题目描述

    你有一个 $n$ 行 $m$ 列的 $01$ 矩阵 $A$ 。
    如果矩阵的第 $i$ 列有奇数个 $1$ ,那么它的权值就是 $a_i imes 3^{b_i}$ ,否则它的权值就是 $0$ 。一个矩阵的权值定义为每列的权值和。
    现在你可以删去这个矩阵的任意多行 (可以为 $0$ ),使得矩阵的权值最大。

    数据范围

    $1 le m le 70$ ; $a_i=±1$ ; $1 le b_i le 35$ ;$b_i e b_j && a_i e a_j$ ; $1 le n le 2 imes 10^5$

    题解

    考虑每一行为一个二进制数,把问题转化成选中一些串行进行异或,得到的串 $c$ 的价值为 $c_i imes a_i imes 3^{b_i}$ ,使其最大。

    考虑按位贪心,用线性基维护异或值,注意考虑 $b_i$ 相同的情况。先看能否只取 $1$ ,否则要使这两位相同,在线性基里加入 $11$ 即可。

    代码

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    int n,m,f[75],g[75],p[75],h[75];
    bool is[75]; LL pw[75];
    bitset<75>b,a[75],c;
    char ch[200005][75];
    LL cal(bitset<75> x){
        LL s=0;
        for (int i=0;i<m;i++)
            if (x[i]) s+=pw[g[p[i]]]*f[p[i]];
        return s;
    }
    bool cmp(int x,int y){
        return g[x]<g[y] || (g[x]==g[y] && f[x]<f[y]);
    }
    void ins(){
        for (int j=m-1;~j;j--)
            if (b[j]){
                if (is[j]) b^=a[j];
                else{a[j]=b;is[j]=1;break;}
            }
    }
    bool check(int x){
        return ((b[x]^h[x])^(b[x-1]^h[x-1]));
    }
    int main(){
        cin>>n>>m;pw[0]=1;
        for (int i=1;i<=35;i++) pw[i]=3ll*pw[i-1];
        for (int i=1;i<=n;i++) scanf("%s",ch[i]);
        for (int i=0;i<m;i++)
            scanf("%d%d",&f[i],&g[i]),p[i]=i;
        sort(p,p+m,cmp);
        for (int i=1;i<=n;i++){
            for (int j=0;j<m;j++)
                b[j]=(ch[i][p[j]]=='1');ins();
        }
        for (int i=0;i<m;i++) if (f[p[i]]>0) h[i]=1;
        for (int i=m-1;~i;i--){
            if (i && g[p[i]]==g[p[i-1]] && is[i] && !is[i-1]){
                b=c;
                bool f1=check(i);
                b^=a[i];
                bool f2=check(i);
                if (f1 && f2){
                    b=a[i];b[i]=b[i-1]=0;ins();
                }
                else if (c[i]^h[i]) c=b;
                i--;continue;
            }
            if (c[i]^h[i]) c^=a[i];
        }
        cout<<cal(c)<<endl;
        return 0;
    }
  • 相关阅读:
    POJ3213(矩阵乘法)
    jquery:ajax不接收返回值回
    Swift UI学习UITableView and protocol use
    也可以看看GCD(杭州电2504)(gcd)
    数据结构—队列
    HDU 4946 Area of Mushroom 凸包
    UVa 353
    照片教你eclipse通过使用gradle 打包Android
    普林斯顿大学公开课 算法1-8:并检查集合 高速查找
    Codeforces Round #246 (Div. 2)
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/12047264.html
Copyright © 2011-2022 走看看