hdu4585 Treap与名次树/STL map(C/C++)
hdu4585
题目地址:https://acm.dingbacode.com/showproblem.php?pid=4585
Shaolin
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
When a young man passes all the tests and is declared a new monk of Shaolin, there will be a fight , as a part of the welcome party. Every monk has an unique id and a unique fighting grade, which are all integers. The new monk must fight with a old monk whose fighting grade is closest to his fighting grade. If there are two old monks satisfying that condition, the new monk will take the one whose fighting grade is less than his.
The master is the first monk in Shaolin, his id is 1,and his fighting grade is 1,000,000,000.He just lost the fighting records. But he still remembers who joined Shaolin earlier, who joined later. Please recover the fighting records for him.
In each test case:
The first line is a integer n (0 <n <=100,000),meaning the number of monks who joined Shaolin after the master did.(The master is not included).Then n lines follow. Each line has two integer k and g, meaning a monk's id and his fighting grade.( 0<= k ,g<=5,000,000)
The monks are listed by ascending order of jointing time.In other words, monks who joined Shaolin earlier come first.
The input ends with n = 0.
3
2 1
3 3
4 2
0
2 1
3 2
4 2
题意
先对老和尚的等级排序,在加入一个新和尚是,找到等级最接近的老和尚,输出老和尚的id。
总复杂度O(nlong n)
<解法一> STL map
AC代码


1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn=1e9;
4 map<int,int> mp;//it->first是等级,it->second是id
5 int main(){
6 int n;
7 while(~scanf("%d",&n)&&n){
8 mp.clear();
9 mp[maxn]=1;//方丈1,等级是1 000 000 000
10 while(n--){
11 int id,g;
12 scanf("%d%d",&id,&g);//新和尚id,等级是g
13 mp[g]=id;//进队
14 int ans;
15 map<int,int>::iterator it=mp.find(g);//找到排好序的位置
16 if(it==mp.begin()) ans=(++it)->second;
17 else{
18 map<int,int>::iterator it2=it;
19 it2--;it++;//等级接近的前后两个老和尚
20 if(g-it2->first<=it->first-g)
21 ans=it2->second;
22 else ans=it->second;
23 }
24 printf("%d %d\n",id,ans);
25 }
26 }
27 return 0;
28 }
<解法二> Treap树
AC代码


1 #include<bits/stdc++.h>
2 using namespace std;
3 int id[5000005];
4 struct node{
5 int size;//以这个结点为根的子树的结点总数量,用于名次树
6 int rank;//优先级
7 int key;//键值
8 node *son[2];//son[0]是左儿子,son[1]是右儿子
9 bool operator<(const node &a)const{return rank<a.rank;}
10 int cmp(int x)const{
11 if(x==key) return -1;
12 return x<key?0:1;
13 }
14 void update(){//更新size
15 size=1;
16 if(son[0]!=NULL) size+=son[0]->size;
17 if(son[1]!=NULL) size+=son[1]->size;
18 }
19 };
20 void rotate(node *&o,int d){//d=0,左旋;d=1,右旋
21 node *k=o->son[d^1];//d^1与1-d等价,但是更快
22 o->son[d^1]=k->son[d];
23 k->son[d]=o;
24 o->update();
25 k->update();
26 o=k;
27 }
28 void insert(node *&o,int x){//把x插入到树中
29 if(o==NULL){
30 o=new node();
31 o->son[0]=o->son[1]=NULL;
32 o->rank=rand();
33 o->key=x;
34 o->size=1;
35 }
36 else{
37 int d=o->cmp(x);
38 insert(o->son[d],x);
39 o->update();
40 if(o<o->son[d]) rotate(o,d^1);
41 }
42 }
43 int kth(node *o,int k){//返回第k大的数
44 if(o==NULL||k<=0||k>o->size) return -1;
45 int s=o->son[1]==NULL?0:o->son[1]->size;
46 if(k==s+1) return o->key;
47 else if(k<=s) return kth(o->son[1],k);
48 else return kth(o->son[0],k-s-1);
49 }
50 int find(node *o,int k){//返回元素k的名次
51 if(o==NULL) return -1;
52 int d=o->cmp(k);
53 if(d==-1) return o->son[1]==NULL?1:o->son[1]->size+1;
54 else if(d==1) return find(o->son[d],k);
55 else{
56 int tmp=find(o->son[d],k);
57 if(tmp==-1) return -1;
58 else return o->son[1]==NULL?tmp+1:tmp+1+o->son[1]->size;
59 }
60 }
61 int main(){
62 int n;
63 while(~scanf("%d",&n)&&n){
64 srand(time(NULL));
65 int k,g;
66 scanf("%d%d",&k,&g);
67 node *root=new node();
68 root->son[0]=root->son[1]=NULL;
69 root->rank=rand();
70 root->key=g;
71 root->size=1;
72 id[g]=k;
73 printf("%d 1\n",k);
74 for(int i=2;i<=n;i++){
75 scanf("%d%d",&k,&g);
76 id[g]=k;
77 insert(root,g);
78 int t=find(root,g);//返回新和尚的名次
79 int ans1,ans2,ans;
80 ans1=kth(root,t-1);//前一名的老和尚
81 ans2=kth(root,t+1);//后一名的老和尚
82 if(ans1!=-1&&ans2!=-1) ans=ans1-g>=g-ans2?ans2:ans1;
83 else if(ans1==-1) ans=ans2;
84 else ans=ans1;
85 printf("%d %d\n",k,id[ans]);
86 }
87 }
88 return 0;
89 }
感觉这段比较难理解的话,可以去看看《算法竞赛入门经典训练指南》(蓝书)P230的3.5.2
函数?拿来吧你
// 讲真,发生了一件比较诡异的事情,我在之前的博客里不是写过一次rotate函数嘛,然后把那边的rotate函数直接复制过来(当然要加上更新,而且必须是先维护o,再维护k)去交的话CE了,但是重打一遍就AC了。。。就离谱/笑哭//笑哭//笑哭/
// 上面提到的之前的博客的地址:https://www.cnblogs.com/ynzhang2020/p/15070994.html
hdu4585 Treap与名次树/STL map(C/C++)的更多相关文章
- Treap 实现名次树
在主流STL版本中,set,map,都是BST实现的,具体来说是一种称为红黑树的动态平衡BST: 但是在竞赛中并不常用,因为红黑树过于复杂,他的插入 5 种,删除 6 中,代码量极大(如果你要改板子的 ...
- Treap和名次树
Treap名字的来源:Tree+Heap,正如名字一样,就是一颗简单的BST,一坨堆的合体.BST的不平衡的根本原因在于基于左<=根<=右的模式吃单调序列时候会无脑成长链,而Treap则添 ...
- 模板——Treap实现名次树
Treap 是一种通过赋予结点随机权值的一种满足堆性质的二叉搜索树,它很好的解决了二叉搜索树顺序插入组成链式的局限性. 名次树是指在treap的每个结点中添加附加域size,表示以它为根的子树的总结点 ...
- 「模板」「讲解」Treap名次树
Treap实现名次树 前言 学平衡树的过程可以说是相当艰难.浏览Blog的过程中看到大量指针版平衡树,不擅长指针操作的我已经接近崩溃.于是,我想着一定要写一篇非指针实现的Treap的Blog. 具体如 ...
- bzoj3224 Tyvj 1728 普通平衡树(名次树+处理相同)
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5354 Solved: 2196[Submit][Sta ...
- STL MAP及字典树在关键字统计中的性能分析
转载请注明出处:http://blog.csdn.net/mxway/article/details/21321541 在搜索引擎在通常会对关键字出现的次数进行统计,这篇文章分析下使用C++ STL中 ...
- uvalive 5031 Graph and Queries 名次树+Treap
题意:给你个点m条边的无向图,每个节点都有一个整数权值.你的任务是执行一系列操作.操作分为3种... 思路:本题一点要逆向来做,正向每次如果删边,复杂度太高.逆向到一定顺序的时候添加一条边更容易.详见 ...
- UVa 1479 (Treap 名次树) Graph and Queries
这题写起来真累.. 名次树就是多了一个附加信息记录以该节点为根的树的总结点的个数,由于BST的性质再根据这个附加信息,我们可以很容易找到这棵树中第k大的值是多少. 所以在这道题中用一棵名次树来维护一个 ...
- LA 5031 Graph and Queries —— Treap名次树
离线做法,逆序执行操作,那么原本的删除边的操作变为加入边的操作,用名次树维护每一个连通分量的名次,加边操作即是连通分量合并操作,每次将结点数小的子树向结点数大的子树合并,那么单次合并复杂度O(n1lo ...
- bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1807 Solved: 772[Submit][Stat ...
随机推荐
- linux 的防火墙 ufw、firwalld、iptables 、
防火墙综述 linux 防火墙,常用的包括三种:ufw . firewalld 和 iptables.学习难度依次递增. ufw 因为原生的 iptable 配置麻烦,学习成本较高. ufw全称 Un ...
- 2.mysql存储过程、存储函数与触发器
-- 创建一个存储过程DELIMITER $CREATE PROCEDURE 存储过程名称(返回类型 参数名1 参数类型1, ....) [ ...... ]BEGIN -- 具体组成存储过程的SQL ...
- 从main_phase跳回reset_phase的方式
在main_phase中调用: phase.jump(uvm_reset_phase::get()); 注意需要防止进入死循环.
- Vue之使用umy-ui库的u-table解决 el-table当存在大量数据时,界面操作卡顿。
提示:一.下面的1. 对应 二.下面的1.:2.则对应2. 错误排查:在使用中如果出现:readding 'style' undefined类似错误的, 可以先排查 u-table中height的值引 ...
- mysql开启root用户远程管理权限
来源:https://blog.csdn.net/qq_29670375/article/details/120590041 1.使用"mysql -uroot -proot"命令 ...
- mysql in和find_in_set
一.查询包含","的列 1.如果查询条件包含单引号 用in 如:select * from t_test where names in ('李红'); 只能查询出names列中值为 ...
- js——带暂停、启动功能的定时
简单的封装,将 interval 二次封装,对外提供暂停.启动功能. 不足之处:interval定时间隔是固定的,在调用异步函数的时候,可能会出现bug.例如:在调用ajax异步请求过程中,发送a.b ...
- [*]Is L2 Physics-Informed Loss Always Suitable for Training Physics-Informed Neural Network?
NeurIPS 2022 本篇工作对PINN中的物理损失进行了探究,作者认为L2损失并不总是适用于训练PINN.并从PDE解的稳定性角度给出了理论性的说明.读了这篇文章,感觉自己的毕业论文做的十分浅显 ...
- CSC落榜
2021年5月31日21:00点,CSC公布结果,未通过.看到这,我感觉空气瞬间凝固,窒息,那一瞬间我无比平静,我以为我会哭,但是,却泣不成声,脑中第一时间想到得是,如何面对认识得人,全世界感觉都知道 ...
- css 启动页 loading动画
<div class="index-html-loader"> <div class="text">Loading...</div ...