题目链接:http://codeforces.com/contest/1288/problem/D
参考:https://www.cnblogs.com/switch-waht/p/12197017.html
给定n*m的数组,(1<=n<=3e5,1<=m<=8)
选择2行,相应的列值取max得到新的一行
,再取
,求一种选择方案,使该值最大。
题解:二分答案,对于当前的cur值,用一个二进制数标记每一行对于cur的大小,如果>=cur则对应标记为1,否则标记为0。之后,check是否存在2个二进制数,其或运算结果为(1<<m)-1。
#include<bits/stdc++.h>
using namespace std;
const int maxn=300010;
int a[maxn][10];
int n,m;
int x,y;
int vis[300];
bool check(int cur){
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
int res=0;
for(int j=1;j<=m;j++){
if(a[i][j]>=cur)
res|=1<<(j-1);
}
vis[res]=i;
}
for(int i=0;i<=255;i++){
for(int j=0;j<=255;j++){
if(vis[i]&&vis[j]&&((i|j)==((1<<m)-1))){
x=vis[i];y=vis[j];
return 1;
}
}
}
return 0;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
int l=0,r=1e9,mid;
while(l<=r){
mid=(l+r)>>1;
if(check(mid)){
l=mid+1;
}else{
r=mid-1;
}
}
printf("%d %d\n",x,y);
return 0;
}