Educational Codeforces Round 80. D - Minimax Problem

题面:https://codeforces.com/contest/1288/problem/D

题目大意:

给定n个序列,每个序列元素个数严格相等于m

你需要找到两个序列a[i]和a[j],使其每个对应位置的元素取大后得到b序列  b[k]=max(a[i][k],a[j][k])

且让b序列中的最小值最大

i可以等于j

解题思路:

二分假设这个b序列的最小值的值x

将a序列转化成01构成的二进制串存在数组b中

0表示当前位置的值<x

1表示当前位置的值>=x

每次便最多可以得到3e5个字符

双层循环i,j从0到255(最大)

只要满足b[i]存在且b[j]存在且b[i]和b[j]按位取或后得到的结果每一位都是1(即a[i]和a[j]这两个数列按照题目所述方式得到的最小值比当前枚举的x大,此时说明二分的x是可行的,返回true)

如果找不到,返回false,说明x二分得太大了

二分的过程中在返回true之前就可以记录一下当前枚举到的i和j

总时间复杂度最坏情况为为O(log1e9 * (3e5+255^2)) 约为O(1e7)满足题意

 1 /*
 2 Written By. StelaYuri
 3 On 2020/01/14
 4 */
 5 #include<bits/stdc++.h>
 6 using namespace std;
 7 int a[300050][10],b[300],n,m,ci,cj,cpd=0;
 8 bool prim(int x){
 9     int i,j,d;
10     memset(b,0,sizeof b);
11     for(i=1;i<=n;i++){
12         d=0;
13         for(j=0;j<m;j++)
14             if(a[i][j]>=x)
15                 d|=(1<<j);
16         b[d]=i;
17     }
18     for(i=0;i<=cpd;i++)
19         for(j=0;j<=cpd;j++)
20             if(b[i]&&b[j]&&((i|j)==cpd)){
21                 ci=b[i];
22                 cj=b[j];
23                 return true;
24             }
25     return false;
26 }
27 int main(){
28     ios::sync_with_stdio(0);
29     cin.tie(0);cout.tie(0);
30     int i,j,l=0,r=1e9,mid;
31     cin>>n>>m;
32     if(n==1){
33         cout<<"1 1\n";
34         return 0;
35     }
36     for(j=0;j<m;j++)
37         cpd|=(1<<j);
38     for(i=1;i<=n;i++)
39         for(j=0;j<m;j++)
40             cin>>a[i][j];
41     while(l<=r){
42         mid=(l+r)>>1;
43         if(prim(mid))
44             l=mid+1;
45         else
46             r=mid-1;
47     }
48     prim(r);//保险起见再处理一次
49     cout<<ci<<‘ ‘<<cj<<endl;
50
51     return 0;
52 }

原文地址:https://www.cnblogs.com/stelayuri/p/12222939.html

时间: 2024-07-31 22:02:19

Educational Codeforces Round 80. D - Minimax Problem的相关文章

【codeforces】Educational Codeforces Round 80 D. Minimax Problem——二分+二进制处理

题目链接 题目大意 有n个维度为m的向量,取其中两个进行合并,合并时每个维度取两者之间的较大者,得到的新的向量中,维度值最小者最大为多少 分析 首先最需要注意的是m的取值,m最大只有8 那么我们可以二分答案,对于每一个二分值,进行下面的操作 将整个矩阵的每一个元素,如果这个元素大于二分值,则变成1,反正则变成0 把每一个向量压缩为单个二进制数 这样我们最多只会得到\(2^8 = 256\)种不同的二进制数,然后暴力的遍历所有可能的二进制数的组合,得到是否满足当前二分值 AC code #incl

Educational Codeforces Round 80 (Rated for Div. 2)

\[Educational\ Codeforces\ Round\ 80\ (Rated\ for\ Div.\ 2)\] A.Deadline 打勾函数找最小值,在\(\sqrt{d}\)邻域里找\(x\)最小化\(x+\lceil\frac{d}{x+1}\rceil\)即可 //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace

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

Educational Codeforces Round 80 A-E简要题解

contest链接:https://codeforces.com/contest/1288 A. Deadline 题意:略 思路:根据题意 x + [d/(x+1)] 需要找到一个x使得上式小于等于n,即x + [d/(x+1) ] <=n,不等式两边同时+1得 x+1 + [d/(x+1)] <=n + 1当且仅当(x+1)2 = d时,式子左边最小,所有只需要判断一下最小值是否<=n+1就可以知道该不等式是否存在x满足题意了,即找到x = √d - 1,判断一下即可. AC代码:

Educational Codeforces Round 80 D E

A了三题,rk1000左右应该可以上分啦,开??. 后面的D,E比赛时就感觉可做,但又想不到方法. 然后我补了下,确实如此. D - Minimax Problem 题意:很简单,给一个矩阵,找两行序列i,j,使得通过每个元素取当列最大合成出来的序列,最小值最大. hit 1:比赛里我是真的有想二分,最小值最大,这不是经典二分答案套路嘛. hit 2:比赛里我也是真的有注意到这个m <=8 给的很小,想以此为突破点干点啥? 然后要么太晚了,要么我做了三题自满了,总之没想到最终解法就睡觉了. 其实

Educational Codeforces Round 80 (Rated for Div. 2) 题解

Deadline Yet Another Meme Problem Two Arrays Minimax Problem Messenger Simulator Deadline \[ Time Limit: 2 s\quad Memory Limit: 256 MB \] 这是个对勾函数,所以最小的话是在 \(sqrt\) 位置,所以只要找这附近的数字就可以了. view /************************************************************

Educational Codeforces Round 80 (Div. 2)

D. Minimax Problem 题意 && 思路 题意: 给出 n 个长度为 m 的序列(1 ≤ n ≤ 3*1e5, 1≤ m ≤8 ),对于序列中的每一个元素 a,(0≤a≤1e9) 现在你要求出,对于所有任意两行序列为一组(或则自己本身成为一组),进行(两个序列的同一个位置取最大值放到新序列中)操作形成新的序列,再从新的序列中选取最小值作为ans,最后要对所有可能组成的ans中输出最大的ans. 思路: 说实话没有想到用二分加二进制压缩表示来求解.二分倒是可以想到,毕竟正向 把

Educational Codeforces Round 80

QAQ: 其中C,D,E题的思路来自 https://www.bilibili.com/video/av83609526?p=5 A. Deadline 题意: 给出一个式子对于给出的d,求当x是整数时的最小解. 思路: 简单数学题,这个式子变形一下就是我们中学学的对号函数,但要注意下向上取整和整数x 代码: #include <bits/stdc++.h> using namespace std; typedef long long LL; int main() { int T; LL n,

Educational Codeforces Round 80. B - Yet Another Meme Problem

题面:https://codeforces.com/contest/1288/problem/B 题目大意: 令conc(a,b)函数得出的结果为将ab拼接得到的数字. 例如:conc(12,23)=1223 a和b不会包括前导0! 接下来,你已知A和B,问有多少对的(a,b)满足 1≤a≤A , 1≤b≤B a*b+a+b=conc(a,b) 解题思路: 想法题,只需要满足b这个数字每一位全为9,那么等式 a*b+a+b=conc(a,b) 恒成立 因为 a*b+a+b=a*(b+1)+b b