Description
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 min k = 1 m b k \min_{k=1}^m b_k 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 min k = 1 m b k \min_{k=1}^m b_k mink=1mbk is maximum possible. If there are multiple answers, print any of them.
Sample Input
6 5
5 0 3 1 2
1 8 9 1 3
1 2 3 4 5
9 1 0 3 7
2 3 0 6 3
6 4 1 7 0
Sample Output
1 5
核心思想:
第一步:
二分枚举v =
min
k
=
1
m
b
k
\min_{k=1}^m b_k
mink=1mbk。
第二步:
对于枚举出的v值,判断它是否可取:
每个序列的最大长度为8,用二进制数表示每个序列中哪些数是不小于v的。
vis[i]=k,表示状态为i的序列可以是第k个序列。
如果(i|j)==(1<<m)-1,则状态i和状态j的组合满足条件,vis[i]和vis[j]就是答案。
详见代码!
代码如下:
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=3e5+20,M=10;
//数组a存原数据,vis从状态映射序列号,w是二进制位权
int n,m,a[N][M],vis[1<<M],w[M],ans1,ans2;
bool fun(int v)
{
int en=1<<m;
//初始化vis
for(int i=0;i<en;i++)
vis[i]=-1;
//获得vis
for(int i=1;i<=n;i++)
{
int t=0;
for(int j=1;j<=m;j++)
if(a[i][j]>=v)
t+=w[j];
vis[t]=i;
}
//两重for循环遍历序列号会超时,遍历状态即可
for(int i=0;i<en;i++)
for(int j=i;j<en;j++)
if(vis[i]!=-1&&vis[j]!=-1&&(i|j)==en-1)
{
ans1=vis[i],ans2=vis[j];
return 1;
}
return 0;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
//初始化位权
w[1]=1;
for(int i=2;i<M;i++)
w[i]=w[i-1]<<1;
//二分
int l=0,r=1e9+10;
while(l<=r)
{
int mid=(l+r)>>1;
if(fun(mid)) l=mid+1;
else r=mid-1;
}
cout<<ans1<<' '<<ans2<<endl;
return 0;
}