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升级系统内核版导致死锁
如上图片,官方说明为linux内核版本过低,存在系统bug,具体说明如下: https://baijiahao.baidu.com/s?id=1652492237858209875&wfr=s ...
- c# reflect里面的getValue()参数
Type ty = t.GetType(); PropertyInfo[] PropertyInfo = ty.GetProperties(); string Typename = typeof(T) ...
- 使用git下载文件时提示身份验证失败
鼠标右键打开Git Bash Here窗口 输入git clone + 网址 后出现身份报错提示信息 需要重新修改一下用户名和邮箱就可以了 git config --global --replace- ...
- ARM-THUMB procedure call standard(ATPCS是ARM-Thumb过程调用标准的简称)
为了使单独编译的c语言和汇编程序之间能够相互调用,必须为子程序之间的调用规定一定的规则.ATPCS就是ARM程序和Thumb程序中子程序的基本规则. 基本ATPCS规定了在子程序调用时的一些基本规则, ...
- 从零搭建hadoop集群之系统管理操作
1. 配置主机名 [root@hadoop01 ~]# hostname #显示当前主机名 方法一:通过配置文件/etc/hostname (重启后生效) [root@hadoop01 ~]# vim ...
- JS实现打字效果(_会闪烁)
背景 更新博客园个人博客时,突发奇想想要将子标题的入场特效做成类似Linux命令行输命令时的样式 效果网页:LanceEst - 博客园 (cnblogs.com) 思路和代码 1 <h2 id ...
- tiktok运营工具
1.自信点!这就是TikTok最全运营工具合集! - 知乎 (zhihu.com) 2.骄傲的和大家说!这就是TikTok最全运营工具合集! - 知乎 (zhihu.com) 3.如何批量去水印下载抖 ...
- Java-面向对象进阶 方法继承、重写
1.继承 子类继承父类后自动拥有父类非私有的属性和方法 Java中,一个父类可以被多个子类继承,一个子类只能继承一个父类 除了继承父类的属性和方法外,子类还拥有自己特有的属性和方法 如果子类的方法与父 ...
- CF513F2 题解
题意 传送门 有 \(a+b+1\) 个会动的棋子,在一个大小为 \(n\times m\) 的棋盘上,棋盘上有一些点有障碍.棋子中,有 \(a\) 个红色棋子,\(b\) 个蓝色棋子,和 \(1\) ...
- 【剑指Offer】【树】树的子结构
题目:输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) /* struct TreeNode { int val; struct TreeNode *left ...