UVA 11020 Efficient Solutions (BST,Splay树)
题意:给n个坐标。一个坐标(x,y)若有无存在的坐标满足x1<x && y1<=y 或 x1<=x && y1<y 时,此坐标(x,y)是就是有优势的。在给每一个坐标之后,立刻输出当前有优势的坐标有多少个。
思路:Set可以做,但是我用Splay树实现也不难。观察题意中的不等式发现,一个点(x,y)的左下方不能有点(相当于跟(0,0)组成的矩形中不能有其他点,除了(x,y)之外),但是若有相同的点的存在,这些相同点都是优势点。
用Splay维护剩下的全部优势点,对于新来的一个点,如果它本来就被其他已经存在的优势点所淘汰,则不必插入树了。若没有被淘汰,插入它后,它有可能会淘汰其他点,如果我们根据x坐标来排序的话,有可能被淘汰的点就在新插入的点的右边,只要右边有点(x1,y1)满足y1>=y就会淘汰掉该点。
#include <bits/stdc++.h>
#define pii pair<int,int>
#define INF 0x3f7f7f7f
#define LL long long
using namespace std;
const int N=;
const int mod=; struct node
{
int key, y, pre, flip, ch[], son[];
}nod[N];
int n, node_cnt, root; int create_node(int v,int y,int far) //以x来排序即可。
{
nod[node_cnt].key=v;
nod[node_cnt].y=y;
nod[node_cnt].pre=far;
nod[node_cnt].flip=;
nod[node_cnt].ch[]=;
nod[node_cnt].ch[]=;
nod[node_cnt].son[]=;
nod[node_cnt].son[]=;
return node_cnt++;
} void Rotate(int t,int d)
{
int son=nod[t].ch[d];
int far=nod[t].pre;
int gra=nod[far].pre; nod[son].pre=far;
nod[far].pre=t;
nod[t].pre=gra; nod[t].ch[d]=far;
nod[far].ch[d^]=son;
nod[gra].ch[ nod[gra].ch[]==far ]=t; nod[far].son[d^]=nod[t].son[d];
nod[t].son[d]+=nod[far].son[d]+;
} int Insert(int t,int v,int y)
{
if(t==) return root=create_node(v, y, );
if( v==nod[t].key ) //x相同,必有人被淘汰
{
if(nod[t].y<y) return ; //此人无效
if(nod[t].ch[]) return Insert(nod[t].ch[], v, y); //插在其前面
else return nod[t].ch[]=create_node(v, y, t);
}
else if( v<nod[t].key )
{
if(nod[t].ch[]) return Insert(nod[t].ch[], v, y);
else return nod[t].ch[]=create_node(v, y, t);
}
else
{
if(nod[t].ch[]) return Insert(nod[t].ch[], v, y);
else return nod[t].ch[]=create_node(v, y, t);
}
} void Splay(int t,int goal)
{
while(nod[t].pre!=goal)
{
int f=nod[t].pre, g=nod[f].pre;
if(g==goal) Rotate(t, nod[f].ch[]==t);
else
{
int d1=nod[f].ch[]==t, d2=nod[g].ch[]==f;
if(d1==d2) Rotate(f, d1),Rotate(t, d1);
else Rotate(t, d1),Rotate(t, d2);
}
}
if(!goal) root=t;
} int Find_del_node(int t,int y)
{
if(t==) return ; //无后继了
if(nod[t].y>=y ) return t;
int q;
if(nod[t].ch[] && (q=Find_del_node(nod[t].ch[], y)) ) return q;
if(nod[t].ch[] && (q=Find_del_node(nod[t].ch[], y)) ) return q;
return ;
} int Find_bac(int t,int d) //这个可以找前驱也可以找后继。d为1则前驱。
{
if(t==) return ;
if(nod[t].ch[d]==) return t;
else return Find_bac(nod[t].ch[d], d);
} void Delete(int t) //专门删除根节点
{
int L=nod[t].ch[], R=nod[t].ch[];
if(R==) //无后继
{
root=L;
nod[root].pre=;
}
else //找后继
{
R=Find_bac(R, );
Splay( R, root);
nod[R].ch[]=L;
nod[R].pre=;
nod[R].son[]=nod[L].son[]++nod[L].son[];
nod[L].pre=R;
root=R;
}
} int main()
{
//freopen("input.txt", "r", stdin);
int t, k, a, b, ans, Case=;
cin>>t;
while(t--)
{
printf("Case #%d:\n", ++Case);
node_cnt=;
root=;
scanf("%d",&n);
for(int i=; i<n; i++)
{
scanf("%d%d", &a, &b);
int ok=Insert(root, a, b);
if(ok!=) //碰到x相同的,而且y又比它大,那么直接无效。但是并不是一定是优势点。
{
Splay(ok, ); //插入成功,先伸展到根。
int r=Find_bac(nod[root].ch[], ); //找前驱
if( r && nod[r].key<a && b>=nod[r].y) Delete(root); //新点为非优势点
else
{
while( (k=Find_del_node(nod[root].ch[], b))!= ) //从右边开始,找到一个删一个。
{
Splay(k, );
Delete(root);
Splay(ok, );
}
}
}
printf("%d\n", nod[root].son[]++nod[root].son[]); //输出树上有多少点
}
if(t) printf("\n");
}
return ;
}
AC代码
UVA 11020 Efficient Solutions (BST,Splay树)的更多相关文章
- UVa 11020 Efficient Solutions (BST)
题意:给按顺序给定 n 个人群,用x和y来描述,如果有没有任何一个x' < x y' <= y 或 x '<= x y' <= y,那么这个群体就是优势群体, 让你求出每放入一 ...
- UVA 11020 - Efficient Solutions(set)
UVA 11020 - Efficient Solutions 题目链接 题意:每个人有两个属性值(x, y).对于每个人(x,y)而言,当有还有一个人(x', y'),假设他们的属性值满足x' &l ...
- uva 11020 - Efficient Solutions ——平衡BST
链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&am ...
- STL(multiset) UVA 11020 Efficient Solutions
题目传送门 题意:训练指南P228 分析:照着书上的做法,把点插入后把它后面不占优势的点删除,S.size ()就是优势的人数,时间复杂度O (nlogn) #include <bits/std ...
- UVa 11020 Efficient Solutions(平衡二叉树/multiset )
题意:有n个人,每个人有x.y两个属性,每次输入一个人(x,y).如果当前不存在一个人(x`,y`)的属性满足x`<=x,y`<y或者x`<x,y`<=y,就说这个人是有优势的 ...
- uva 11020 Efficient Solutions
题意:给你n个人,有两个属性x.y,如果不存在另外一个人x2,y2满足 x2<=x,y2<y 或者 x2<x,y2<=y,那么就称这个人是有优势的,每次给你一个人得信息,问你当 ...
- UVA - 11020 Efficient Solutions(Multiset)
本题利用multiset解决.根据题意,如果我们用P(x,y)表示一个人,因为人可以相同,所以用multiset.我们会发现,如果所有人群都是有优势的,那么这些点呈现一个递减的趋势.如果刚刚插入一个人 ...
- UVA 11020 Efficient Solutions+multiset的应用
题目链接:点击进入 首先来讲,非常easy看到我们事实上仅仅要维护优势人群的集合:假设增加一个新的人,我们首先看一下优势人群中是否有人会让这个人失去优势,假设没有,则将这个人插入集合中.但要注意到这个 ...
- UVA 11922 Permutation Transformer (Splay树)
题意: 给一个序列,是从1~n共n个的自然数,接下来又m个区间,对于每个区间[a,b],从第a个到第b个从序列中分离出来,翻转后接到尾部.输出最后的序列. 思路: 这次添加了Split和Merge两个 ...
随机推荐
- ubuntu下tesseract 4.0安装及参数使用
tesseract是一个开源的OCR引擎,最初是由惠普公司开发用来作为其平板扫描仪的OCR引擎,2005年惠普将其开源出来,之后google接手负责维护.目前稳定的版本是3.0.4.0版本加入了基 ...
- macbook pro 一些操作经验记录
[一]启用root用户 (1)打开终端 (2)输入命令:sudo passwd root (3)给root设置密码 (4)然后再终端输入命令:su root 进行登陆 [二]解压eclipse压缩包, ...
- 「LuoguP3865」 【模板】ST表 (线段树
题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1) 题目描述 给定一个长度为 N 的数列,和 M 次询问,求出每一 ...
- 任务37:生成 JWT Token
实现给用户办法token 默认是可以访问valuesController的,返回的状态是200 http://localhost:5429/api/values 返回的状态码是200 把ValuesC ...
- [NEXT] 时间管理实践
此文已由作者杨卫强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 我个人认为,浪费时间比较主要的原因有两个 工作缺乏计划 工作过程被打扰,效率低下 以下记录我自己的时间管理实 ...
- POJ 1384【完全背包】
题意: 已知储蓄罐满时的质量f以及空时质量e, 有n种硬币,每种硬币的价值为p,质量为w, 求该储蓄罐中的最少有多少钱? 思路: 完全背包思想,问题是在一个重量下的最小价值 那么只要变一下符号就好了? ...
- 洛谷P4841 城市规划(多项式求逆)
传送门 这题太珂怕了……如果是我的话完全想不出来…… 题解 //minamoto #include<iostream> #include<cstdio> #include< ...
- 黑客攻防技术宝典web实战篇:工具web服务器习题
猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 随书答案. 1. 在什么情况下 Web 服务器会显示目录列表? 如果请求某目录的 URL 且满足以下条件,W ...
- [USACO10FEB]购买巧克力Chocolate Buying 【假背包真贪心】 By cellur925
题目传送门 继续dp刷题计划,看到这道题,第一眼感觉不就是显然的完全背包嘛.把背包打完要开始填充数组大小的时候成为了mengbier,发现数据极大,达到了1e18.显然这不是一道平凡的背包题目. 于是 ...
- python之请求报文对比(假定最多二维字典)
两段请求报文,判断不一样的key和value,只判断d2里和d1不同的值,和全部不同的key ok_req={ "version": "9.0.0", &quo ...