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 docker的安装和使用
Docker CE for Ubuntu Docker CE for Ubuntu is the best way to install the Docker platform on Ubuntu L ...
- 【字符串】BZOJ上面几个AC自动机求最为字串出现次数的题目
(一下只供自己复习用,目的是对比这几个题,所以写得不详细.需要细节的可以参考其他博主) [BZOJ3172:单词] 题目: 某人读论文,一篇论文是由许多(N)单词组成.但他发现一个单词会在论文中出现很 ...
- ASP.NET WebServce项目下添加Http服务,支持Get,Post请求方式;传输格式json/xml
由于WEBServce老项目中需要增添新的接口,而且添加的接口不希望被其它项目以引用Servces方式使用. 那么得在现有Service项目中添加Http请求方式来实现系统间数据交互.只需要告知请求地 ...
- 「LuoguP3865」 【模板】ST表 (线段树
题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1) 题目描述 给定一个长度为 N 的数列,和 M 次询问,求出每一 ...
- BZOJ1499 单调队列+DP
1499: [NOI2005]瑰丽华尔兹 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 1560 Solved: 949[Submit][Status] ...
- 【旧文章搬运】如何从EPROCESS辨别一个进程是否已退出
原文发表于百度空间,2008-7-31========================================================================== 前面已经通过 ...
- 洛谷 - P1142 - 轰炸 - 计算几何
https://www.luogu.org/problemnew/show/P1142 枚举一个基点,枚举另一个点找出斜率,约分后存入.记得要加上那个点本身. __gcd(x,y),返回值符号与y的符 ...
- bzoj 4698: Sdoi2008 Sandy的卡片【SAM】
差分之后用SAM求LCS,然后答案就是LCS+1 #include<iostream> #include<cstdio> #include<cstring> usi ...
- springcloud(二) 负载均衡器 ribbon
代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo ribbon是一个负载均衡客户端 类似nginx反向代理,可 ...
- jQuery笔记之热点搜索排名小demo
先来看一下成品图: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...