zoukankan      html  css  js  c++  java
  • [CF1288D] Minimax Problem

    给定一个 (nleq 3 imes 10^5)(m leq 8) 列的数字矩阵 (a),找出两行 (x,y),使得 (min_{j=1}^m max(a_{x,j},a_{y,j})) 最大

    Solution

    二分答案,考虑检验 (mid),将每一行大于等于 (mid) 的数设为 (1),反之设为 (0),压位后扔进桶,往 (1) 方向做一下高维前缀和,然后扫一遍桶即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 300005;
    
    int n,m,a[N][9],b[256],c[256],p,y;
    
    int check(int x) {
        memset(b,0,sizeof b);
        for(int i=1;i<=n;i++) {
            int t=0;
            for(int j=0;j<m;j++) {
                if(a[i][j]>=x) t|=1<<j;
            }
            b[t]=1;
            c[t]=i;
        }
        for(int i=(1<<m)-1;i>=0;--i) {
            for(int j=0;j<m;j++) {
                b[i&(~(1<<j))]|=b[i];
                if(b[i]) c[i&(~(1<<j))]=c[i];
            }
        }
        for(int i=1;i<=n;i++) {
            int t=0;
            for(int j=0;j<m;j++) {
                if(a[i][j]>=x) t|=1<<j;
            }
            if(b[(1<<m)-t-1]) {
                p=i;
                y=c[(1<<m)-t-1];
                return 1;
            }
        }
        return 0;
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>m;
        for(int i=1;i<=n;i++) {
            for(int j=0;j<m;j++) {
                cin>>a[i][j];
            }
        }
        int l=0,r=1e9+1;
        while(l<r) {
            int mid=(l+r)/2;
            if(check(mid)) l=mid+1;
            else r=mid;
        }
        check(l-1);
        cout<<p<<" "<<y<<endl;
    }
    
    
  • 相关阅读:
    BZOJ 2653 middle
    BZOJ 3207 花神的嘲讽计划Ⅰ
    BZOJ 3689 异或之
    BZOJ 3037 创世纪
    BZOJ [1264] [ AHOI2006]基因匹配Match
    BZOJ 2186 [Sdoi2008]沙拉公主的困惑
    BZOJ 3362 Navigation Nightmare
    BZOJ 3209 花神的数论题
    BZOJ 1411 ZJOI2009 硬币游戏
    【HDU1573】X问题
  • 原文地址:https://www.cnblogs.com/mollnn/p/12592300.html
Copyright © 2011-2022 走看看