Educational Codeforces Round 80 (Rated for Div. 2) D. Minimax Problem

D. Minimax Problem
time limit per test
5 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

You are given nn arrays a1a1, a2a2, ..., anan; each array consists of exactly mm integers. We denote the yy-th element of the xx-th array as ax,yax,y.

You have to choose two arrays aiai and ajaj (1i,jn1≤i,j≤n, it is possible that i=ji=j). After that, you will obtain a new array bb consisting of mmintegers, such that for every k[1,m]k∈[1,m] bk=max(ai,k,aj,k)bk=max(ai,k,aj,k).

Your goal is to choose ii and jj so that the value of mink=1mbkmink=1mbk is maximum possible.

Input

The first line contains two integers nn and mm (1n31051≤n≤3⋅105, 1m81≤m≤8) — the number of arrays and the number of elements in each array, respectively.

Then nn lines follow, the xx-th line contains the array axax represented by mm integers ax,1ax,1, ax,2ax,2, ..., ax,max,m (0ax,y1090≤ax,y≤109).

Output

Print two integers ii and jj (1i,jn1≤i,j≤n, it is possible that i=ji=j) — the indices of the two arrays you have to choose so that the value of mink=1mbkmink=1mbk is maximum possible. If there are multiple answers, print any of them.

Example
input
Copy
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
output
Copy
1 5

 1 /*
 2 看到题目首先想到的就是二分答案,那么找到一个可能的答案之后就可以把所有数列转化成01数列,1代表该位置的数大于等于答案,0代表该位置的数小于答案。
 3 
 4 选择两个数列使其满足答案,也就是使这两个数列的或和为(1<<m)-1,很显然不能n*n的枚举每个数列,但是2^8只有256,所以可以直接枚举数列对应的二进制数,判断答案是否可行,如果可行,就可以O(n)地寻找可行解
 5 */
 6 #include<iostream>
 7 #include<cstdio>
 8 #include<bitset>
 9 #include<cstring>
10 using namespace std;
11 int n,m,a[300010][10],ans1,ans2;
12 int b[300010];
13 bool vis[300];
14 bool check(int x){
15     memset(b,0,sizeof(b));
16     for(int i=1;i<=n;i++){
17         for(int j=1;j<=m;j++){
18             if(a[i][j]>=x)b[i]^=1<<(j-1);
19         }
20     }
21     memset(vis,0,sizeof(vis));
22     for(int i=1;i<=n;i++)vis[b[i]]=1;
23     bool flag=0;
24     int s1=0,s2=0;
25     for(int sta1=0;sta1<(1<<m);sta1++){
26         for(int sta2=sta1;sta2<(1<<m);sta2++){
27             if((sta1|sta2)==(1<<m)-1&&vis[sta1]&&vis[sta2]){
28                 s1=sta1;s2=sta2;
29                 flag=1;
30                 break;
31             }
32         }
33         if(flag)break;
34     }
35     if(!flag)return 0;
36     for(int i=1;i<=n;i++){
37         if(b[i]==s1){
38             ans1=i;
39             break;
40         }
41     }
42     for(int i=1;i<=n;i++){
43         if(b[i]==s2){
44             ans2=i;
45             break;
46         }
47     }
48     return 1;
49 }
50 int main(){
51     scanf("%d%d",&n,&m);
52     for(int i=1;i<=n;i++)
53         for(int j=1;j<=m;j++){
54             scanf("%d",&a[i][j]);
55         }
56     int l=0,r=1000000000;
57     while(l<=r){
58         int mid=(l+r)>>1;
59         if(check(mid)){
60             l=mid+1;
61         }
62         else r=mid-1;
63     }
64     printf("%d %d\n",ans1,ans2);
65     return 0;
66 }

 

posted @ 2020-01-28 10:56  Echo宝贝儿  阅读(183)  评论(0编辑  收藏  举报