You are given n arrays a1, a2, …, an; each array consists of exactly m integers. We denote the y-th element of the x-th array as ax,y.
You have to choose two arrays ai and aj (1≤i,j≤n, it is possible that i=j). After that, you will obtain a new array b consisting of m integers, such that for every k∈[1,m] bk=max(ai,k,aj,k).
Your goal is to choose i and j so that the value of mink=1mbk is maximum possible.
Input
The first line contains two integers n and m (1≤n≤3⋅105, 1≤m≤8) — the number of arrays and the number of elements in each array, respectively.
Then n lines follow, the x-th line contains the array ax represented by m integers ax,1, ax,2, …, ax,m (0≤ax,y≤109).
Output
Print two integers i and j (1≤i,j≤n, it is possible that i=j) — the indices of the two arrays you have to choose so that the value of mink=1mbk is maximum possible. If there are multiple answers, print any of them.
Example
inputCopy
5
0 3 1 2
8 9 1 3
2 3 4 5
1 0 3 7
3 0 6 3
4 1 7 0
outputCopy
5
思路:最小值最大化问题,绝大概率是二分。但是二分之后的judge环节怎么弄呢?这就是本题的出彩之处。我们将每一个数组中的大于等于mid的位置设置为1,否则就设置为0。这样我们进行或操作,这样出来的就是取最大值操作了。这样如果两两相或,如果各个位上都是1,就代表着当前的mid就是最小值,然后不断的二分,就可以找到最优解了。
代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxx=3e5+100;
int a[maxx][10];
int vis[maxx];
int n,m;
inline bool check(int mid,int &x,int &y)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
int cc=0;
for(int j=1;j<=m;j++) if(a[i][j]>=mid) cc|=(1<<(j-1));
vis[cc]=i;
}
for(int i=0;i<=255;i++)//由于最大就是8位,所以最大是255。
{
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=1000000000;
int x,y;
while(l<=r)
{
int mid=l+r>>1;
if(check(mid,x,y)) l=mid+1;
else r=mid-1;
}
cout<<x<<" "<<y<<endl;
return 0;
}
努力加油a啊,(o)/~