POJ3481 Double Queue (平衡树)【例题精讲】

(这题目莫名让我想到了穿越火线。。。)

题意:编写一个银行应用程序,支持下列操作:

1,加入一个客户(输入:1,k,q) 其中k是客户的编号(不一定是1-n但保证小于一百万),q是客户优先级(整型数好吧)。

2,询问当前优先度最高的客户的编号(输入:2),并且将这个客户删除。

3,询问当前优先度最低的客户的编号(输入:3),并且将这个客户删除。

4,结束操作(输入0)。

 

这道题动态插入询问最大最小显然平衡树,几乎任何一种平衡树都可以做掉。只要记录树的size,优先度为节点的k值,每次find最小或最大即可;

 

下面上代码:

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const int MAXN=1000005;
 8 int key[MAXN],s[MAXN],l[MAXN],r[MAXN];
 9 int t=0,tt=0,q,qq,sign[MAXN],n,m,w,f;
10 void rrotate(int &t){
11     int k=l[t];l[t]=r[k];r[k]=t;
12     s[k]=s[t];s[t]=s[l[t]]+s[r[t]]+1;t=k;
13 }
14 void lrotate(int &t){
15     int k=r[t];r[t]=l[k];l[k]=t;
16     s[k]=s[t];s[t]=s[l[t]]+s[r[t]]+1;t=k;
17 }
18 void maintain(int &t,bool flag){
19     if(!flag){
20         if(s[l[l[t]]]>s[r[t]]) rrotate(t);
21         else if(s[r[l[t]]]>s[r[t]]){
22             lrotate(l[t]);rrotate(t);
23         } else return ;
24     } else{
25         if(s[r[r[t]]]>s[l[t]]) lrotate(t);
26         else if(s[l[r[t]]]>s[l[t]]){
27             rrotate(r[t]);lrotate(t);
28         } else return ;
29     } maintain(l[t],false);maintain(r[t],true);
30     maintain(t,false);maintain(t,true);
31 }
32 void insert(int &t,int v){
33     if(t==0){
34         tt++;t=tt;key[t]=v;
35         s[t]=1;l[t]=r[t]=0;
36     } else{
37         s[t]++;if(v<key[t]) insert(l[t],v);
38         else insert(r[t],v);maintain(t,v>=key[t]);
39     } return ;
40 }
41 int del(int &t,int v){
42     int ret=0;s[t]--;
43     if((v==key[t])||(v<key[t]&&l[t]==0)||(v>key[t]&&r[t]==0)){
44         ret=key[t];if(l[t]==0||r[t]==0) t=l[t]+r[t];
45         else key[t]=del(l[t],key[t]+1);
46     } else{
47         if(v<key[t]) return del(l[t],v);
48         else return del(r[t],v);
49     } return 0;
50 }
51 int select(int &t,int k){
52     if(k==s[l[t]]+1) return t;
53     if(k<=s[l[t]]) return select(l[t],k);
54     else return select(r[t],k-1-s[l[t]]);
55 }
56 int main(){
57     while(~scanf("%d",&f)&&f){
58         if(f==1){
59             scanf("%d%d",&q,&qq);
60             insert(t,qq);sign[tt]=q;
61         } else if(f==2){
62             int cc;if(s[t]==0) puts("0");
63             else printf("%d\n",sign[cc=select(t,s[t])]),del(t,key[cc]);
64         } else{
65             int cc;if(s[t]==0) puts("0");
66             else printf("%d\n",sign[cc=select(t,1)]),del(t,key[cc]);
67         }
68     } 
69     return 0;
70 }
SBT

 

posted @ 2018-08-16 22:07  杜宇一声  阅读(301)  评论(0编辑  收藏  举报