codeforces 38G Queue splay
来源:互联网 发布:淘宝微星旗舰店可信吗 编辑:程序博客网 时间:2024/05/20 12:22
题意:有n个人依次排队,每个人都有两个属性值a[ i ]、c[ i ],a[ i ]是重要性值,数值越大越重要,c[ i ]是良心值。假如第i个人来是排
队,初始时他在队尾,如果他的a[ i ]大于排在他前面那位的重要性值,那么两人可以交换位置,每次交换良心值减1,直到他前面的
人的重要性值大于a[ i ]或者良心值为0的时候,问最终n个人的队列次序。
思路:splay的val存重要性值,Max维护当前子树的最大值。假设当前要插入的人的重要性值为val,我们递归插入。当递归到以x为
根的子树时,设此时这人当前的良心值为sz, 那么如果val < x->ch[ 1 ]->Max 或者 val < x->val 或者 sz <= x->ch[1]->s(右子树的结点
个数)时,只能往右子树递归插入,不然往左子树插入。插入完成后,将其旋转至根。因为splay中维护的val是重要性值,而最后输
出的是排第几个位置的是第几个人,所以需要将val值映射一下,详见代码:
// file name: codeforces38G.cpp //// author: kereo //// create time: 2014年08月26日 星期二 08时40分02秒 ////***********************************//#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<map>#include<vector>#include<stack>#include<cmath>#include<algorithm>using namespace std;typedef long long ll;const int MAXN=100000+100;const int inf=0x3fffffff;#define L(x) (x<<1)#define R(x) (x<<1|1)int n,top,cnt;int st[MAXN];struct node{int s,val,Max;node *fa,*ch[2];}nod[MAXN],nil,*null,*root;map<int,int>mp;struct Splay{void init(){cnt=top=0;nil.s=nil.val=nil.Max=0; null=&nil;newnode(root,null,inf); //最左端newnode(root->ch[1],root,-1); //最右端push_up(root);}void newnode(node *&x,node *f,int val){ //这也一定要用引用,因为你传入的本质是地址常数,而本身你想修改这个数,所以必须要用引用if(top) x=&nod[st[--top]];else x=&nod[cnt++];x->s=1; x->val=x->Max=val; x->fa=f; x->ch[0]=x->ch[1]=null;}void push_up(node *x){x->s=1; x->Max=x->val;if(x->ch[0]!=null) x->s+=x->ch[0]->s, x->Max=max(x->Max,x->ch[0]->Max);if(x->ch[1]!=null) x->s+=x->ch[1]->s, x->Max=max(x->Max,x->ch[1]->Max);}void rotate(node *x,int d){node *y=x->fa; //保证y不为null//push_down(y); push_down(x);y->ch[d^1]=x->ch[d];if(x->ch[d]!=null) x->ch[d]->fa=y;x->fa=y->fa;if(y->fa!=null){int d1=y->fa->ch[0] == y ? 0 : 1;y->fa->ch[d1]=x;}x->ch[d]=y; y->fa=x;push_up(y);}void splay(node *x,node *f){//push_down(x);while(x->fa!=f){node *y=x->fa;if(y->fa == f){int d=y->ch[0] == x ? 1 : 0;rotate(x,d);}else{int d=y->fa->ch[0] == y ? 1 : 0;if(y->ch[d] == x){ //之字型rotate(x,d^1); rotate(x,d);}else{//一字型rotate(y,d); rotate(x,d);}}}push_up(x);if(f == null) root=x;}void insert(node *&x,node *f,int val,int sz){ //考虑能否插到x之前if(x == null){newnode(x,f,val);return ;}if(val<x->ch[1]->Max || val<x->val || sz<x->ch[1]->s) //注意是sz<x->ch[1]->s,因为里面有一个自己设的R(root)结点insert(x->ch[1],x,val,sz);else insert(x->ch[0],x,val,sz-x->ch[1]->s-1);push_up(x);}}spt;void dfs(node *x){if(x->ch[0]!=null)dfs(x->ch[0]);if(x->val!=-1 && x->val!=inf)printf("%d ",mp[x->val]);if(x->ch[1]!=null)dfs(x->ch[1]);}int main(){while(~scanf("%d",&n)){mp.clear(); spt.init();for(int i=1;i<=n;i++){int a,c;scanf("%d%d",&a,&c);spt.insert(root,null,a,c);spt.splay(&nod[cnt-1],null);mp[a]=i;}dfs(root);printf("\n");}return 0;}
0 0
- codeforces 38G Queue splay
- Codeforces 38G Queue 伸展树
- 【CodeForces】38G Queue 伸展树
- Codeforces Beta Round #38 G Queue 动态树
- codeforces Gym 100431G Persistent Queue
- poj3481 Double Queue splay
- POJ3481 Double Queue (Splay)
- 【Codeforces38G】Queue【Splay】【二分】
- hdu3436 Queue-jumpers(Splay)
- Queue CodeForces
- Queue CodeForces
- hdu 3436 Queue-jumpers(Splay)
- 【splay tree】 HDOJ Queue-jumpers
- hdu 1908 Double Queue ( splay )
- poj 3481 Double Queue splay
- 【HDU 4441】 Queue Sequence(Splay)
- 【HDU3436】 Queue-jumpers (Splay tree)
- HDU 4441 【Splay】 Queue Sequence
- Valgrind的快速入门指南
- 常见的Java WEB服务器
- 软件工程的生命周期
- 算法之母函数篇
- Java基础知识(5)
- codeforces 38G Queue splay
- Linux 有趣命令
- 【Andorid开发框架学习】之Mina开发之服务器开发
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第八部---怪物出场
- 【Android小项目】找不同,改编自"寻找房祖名"的一款开源小应用。
- Eclipse下配置CDT和MinGW终极方法。
- LINUX设备驱动程序笔记(一)设备驱动程序简介
- 通过两个触摸点实现视图的缩放(iOS)
- oracle表结构导出导入