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
原创粉丝点击