[二分,multiset] 2019 Multi-University Training Contest 10 Welcome Party
Welcome Party
Time Limit: 4000/4000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 875 Accepted Submission(s): 194
To cope with this problem, the director proposes a model. In this model, every student has two attributes: the singing ability and crosstalking ability. The satisfactory value of audiences to singings is the maximum singing ability among all students that choose to sing a song; similarly, the satisfactory value to crosstalks is the maximum crosstalking ability among all students that choose play crosstalk. The strange thing is, the overall satisfactory value to the whole party is negatively related to the absolute difference between the satisfactory values to singings and crosstalks. The problem is, what is the minimum possible absolute difference between the satisfactory values of the two types of programs?
Note that:
- every student should choose exactly one type of programs to play;
- at least one student should sing a song, and at least one student should play crosstalk.
Each test case starts with a line of a single integer n (2≤n≤100000), denoting the number of students applying to show up on the stage. Then follow n lines, each containing two integers x and y (0≤x,y≤1018), denoting the singing ability and crosstalking ability of a student.
It is guaranteed that the sum of n over all test cases never exceeds 1000000.
5
27 46
89 13
55 8
71 86
22 35
3
3 5
4 7
6 2
1
题意:
有n个学生,每个学生有x值和y值,每个学生必须要么进入x集合要么y集合,x集合的代表值是这个集合中最大的x值,y集合同理,问如何分配学生才能使得x集合代表值与y集合的代表值差值最小
思路:
n最大1e5,所以复杂度最大只能为O(nlogn),可以考虑遍历x集合的同时二分y集合
用一个结构体存学生的x值和y值,并对对学生按x和y降序排序,将学生的y值加入到multiset中
因为现在是降序排序,所以如果选了一个学生代表x集合的代表,则x比他大的学生都必须要加入到y集合中,而比小于等于他的那些则可以随意
所以我们枚举每个学生当x集合的代表,并将其在y集合中的值删掉,用maxn维护必须要加入y集合的那些值的最大值,multiset维护可能可以加入y集合的值,并multiset中二分一个和他最接近的值(可能大于,等于或小于,所以如果it!=s.end()还有it--判断),
当然这个值要比()才能更新ans,再用maxn和现在这个学生x值的差值更新ans,这个学生判断完后就去判断下一个学生,当然因为我们对他们x值降序排序了,所以这个学生就必须加入y集合,用其y值更新maxn
注意(坑点,WA了几十次TAT):
1.maxn代表必定要分到另一个集合的元素的最大值,而第一次没有必须要分到另一个集合中的元素,所以第一次是不能调用的
2.因为一个集合的代表值是这个集合中所以元素中的最大值,所以二分到的值必须要大于maxn才能更新ans
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int amn=1e5+;
struct node{
ll x,y;
}a[amn];
multiset<ll> s;
multiset<ll>::iterator it;
bool cmp(node a,node b){
if(a.x==b.x)return a.y>b.y;
return a.x>b.x;
}
int main(){
int n,T;
bool f;
ll ans,maxn;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%lld%lld",&a[i].x,&a[i].y);
s.insert(a[i].y); ///将y值插入multiset
}
sort(a+,a++n,cmp); ///对学生按x降序排序
ans=1e18;
maxn=; ///maxn维护一个必须要加入y集合的学生中y值最大的值
for(int i=;i<=n;i++){
s.erase(s.find(a[i].y)); ///因为现在把当前学生分到x集合中,所以删除当前学生在multiset中的y值
if(i>)ans=min(ans,abs(a[i].x-maxn)); ///这里是关键,maxn代表必定要分到另一个集合的元素的最大值,而第一次没有必须要分到另一个集合中的元素,所以第一次是不能调用的,否则因为一开始maxn为0,所以第一次会将ans更新为a[1].x
it=s.lower_bound(a[i].x); ///在multiset中二分一个和当前学生x值最接近的值
if(it!=s.begin()&&it==s.end())it--; ///lower_bound会返回第一个大于等于搜索值的地址,如果不存在则返回s.end(),所以如果迭代器不是s.begin()且是s.end()则要将其指向上一个元素
if(*it>=maxn)ans=min(ans,abs(a[i].x-*it)); ///因为一个集合的代表值是这个集合中所以元素中的最大值,所以二分到的值必须要大于maxn才能更新ans
if(it!=s.begin()){ ///如果前面还有元素,则看上一个元素是否符合条件
it--;
if(*it>=maxn)ans=min(ans,abs(a[i].x-*it));
}
maxn=max(maxn,a[i].y); ///现在这个学生必须要被加到y集合中了,更新一下maxn
}
printf("%lld\n",ans);
}
}
/**
有n个学生,每个学生有x值和y值,每个学生必须要么进入x集合要么y集合,x集合的代表值是这个集合中最大的x值,y集合同理,问如何分配学生才能使得x集合代表值与y集合的代表值差值最小
n最大1e5,所以复杂度最大只能为O(nlogn),可以考虑遍历x集合的同时二分y集合
用一个结构体存学生的x值和y值,并对对学生按x和y降序排序,将学生的y值加入到multiset中
因为现在是降序排序,所以如果选了一个学生代表x集合的代表,则x比他大的学生都必须要加入到y集合中,而比小于等于他的那些则可以随意
所以我们枚举每个学生当x集合的代表,并将其在y集合中的值删掉,用maxn维护必须要加入y集合的那些值的最大值,multiset维护可能可以加入y集合的值,并multiset中二分一个和他最接近的值(可能大于,等于或小于,所以如果it!=s.end()还有it--判断),
当然这个值要比()才能更新ans,再用maxn和现在这个学生x值的差值更新ans,这个学生判断完后就去判断下一个学生,当然因为我们对他们x值降序排序了,所以这个学生就必须加入y集合,用其y值更新maxn
注意(坑点):
1.maxn代表必定要分到另一个集合的元素,而第一次没有必须要分到另一个集合中的元素,所以第一次是不能调用的
2.因为一个集合的代表值是这个集合中所以元素中的最大值,所以二分到的值必须要大于maxn才能更新ans
**/
[二分,multiset] 2019 Multi-University Training Contest 10 Welcome Party的更多相关文章
- 2016 Multi-University Training Contest 10
solved 7/11 2016 Multi-University Training Contest 10 题解链接 分类讨论 1001 Median(BH) 题意: 有长度为n排好序的序列,给两段子 ...
- hdu 5416 CRB and Tree(2015 Multi-University Training Contest 10)
CRB and Tree Time Limit: 8000/4000 MS (J ...
- 2015 Multi-University Training Contest 10 hdu 5406 CRB and Apple
CRB and Apple Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- 2015 Multi-University Training Contest 10 hdu 5412 CRB and Queries
CRB and Queries Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- 2015 Multi-University Training Contest 10(9/11)
2015 Multi-University Training Contest 10 5406 CRB and Apple 1.排序之后费用流 spfa用stack才能过 //#pragma GCC o ...
- 2019 Multi-University Training Contest 10
目录 Contest Info Solutions C - Valentine's Day D - Play Games with Rounddog E - Welcome Party G - Clo ...
- 【2019 Multi-University Training Contest 10】
01: 02: 03:https://www.cnblogs.com/myx12345/p/11671692.html 04: 05:https://www.cnblogs.com/myx12345/ ...
- [概率] HDU 2019 Multi-University Training Contest 10 - Valentine's Day
Valentine's Day Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others ...
- [dfs] HDU 2019 Multi-University Training Contest 10 - Block Breaker
Block Breaker Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)T ...
随机推荐
- Android 粘合剂'Binder'
背景知识 要详细掌握Android 的Binder通信机制需要先提前了解一些通信原理与Linux系统的基础知识. RPC RPC(Remote Procedure Call),即远程过程调用,也被称为 ...
- ES:在线迁移集群索引,数据不丢失
一.背景 生产环境由于某些原因需要跨机房迁移ES集群,或者同机房原有集群中所有节点全部更换,期间ES索引要求完整,客户端请求中断不超过五分钟. 二.应用场景 1.同机房不同集群之间数据迁移: 2.跨机 ...
- 空间数据导入Oracle数据库备忘
- 笔记: SpringBoot + VUE实现数据字典展示功能
最近一直在写前端,写得我贼难受,从能看懂一些基础的代码到整个前端框架撸下来鬼知道我经历了啥(:´д`)ゞ 项目中所用到的下拉菜单的值全部都是有数据库中的数据字典表来提供的,显示给用户的是的清晰的意思, ...
- 如何在自己的CSDN博客中增添【高大上】的博客栏目?
前几天看到过一位博主的博客界面,向下看 ☟ (博主对不起啊!把你的公众号给抹了~~~),感觉做这个东西挺好玩的,而且我竟然找不到在哪个地方可以设置!在百度上也没有搜到教程,最后问了一下贺老师知道了入口 ...
- harbor自动清理镜像
harbor定时清理镜像 分享下最近写harbor仓库镜像自动清理脚本思路,很长时间不写shell脚本,这次的脚本也是匆匆写的,还有很多可优化点,感兴趣的可以参考自己优化下,写的不完善地方也希望指 ...
- tab 切换下划线跟随实现
HTML 结构如下: <ul> <li class="active">不可思议的CSS</li> <li>导航栏</li> ...
- Vmware安装的linux系统开机黑屏,关闭显示虚拟机忙怎么怎么解决?
在vm虚拟机中,可能会遇到打开一台主机直接黑屏,而且无法关闭,关闭会显示虚拟机繁忙这种情况,如下图: 一般是因为没有正常关机或者操作不当导致的 对此,解决办法一般有两种 第一种方法: 1.重启电脑 ...
- Python3关于current_app传递给子线程
在学习Flask的时候,<Flask Web开发>这本书中有一个异步发送email的例子,其中用到了线程 from . import mail,create_app def send_as ...
- 并发工具类的使用 CountDownLatch,CyclicBarrier,Semaphore,Exchanger
1.CountDownLatch 允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助. A CountDownLatch用给定的计数初始化. await方法阻塞,直到由于countDo ...