码迷,mamicode.com
首页 > 其他好文 > 详细

Noi2004郁闷的出纳员-treap树

时间:2017-03-06 20:45:07      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:using   sum   root   删除   while   and   treap   ota   nod   

 treap树只需要单旋,可以写在一个函数中。
当需要删除某点时只需不断将这个点下旋知道它只有少于一个的儿子,让他的 儿子 或者 空 取代它。
插入时先插入,然后从底下向上通过旋转维护堆的性质。
下面附标程:

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 struct Node{
 7        int ch[2];
 8        int key,size,pri;
 9        void set(int x){ch[0]=ch[1]=0;key=x;size=1;pri=rand();}
10 }tree[1000000];
11 int tree_size,root,sum,all;
12 int n,minn;
13 void update(int v){
14      tree[v].size=1;
15      if(tree[v].ch[0]) tree[v].size+=tree[tree[v].ch[0]].size;
16      if(tree[v].ch[1]) tree[v].size+=tree[tree[v].ch[1]].size;
17 }
18 void rotate(int &v,int f){
19      int y=tree[v].ch[f];
20      tree[v].ch[f]=tree[y].ch[!f];
21      tree[y].ch[!f]=v;
22      update(v);update(y);
23      v=y;
24 }   
25 void insert(int &v,int x){
26      if(v==0){tree[v=++sum].set(x);}
27      else{
28           tree[v].size++;
29           int f=!(x<=tree[v].key);
30           insert(tree[v].ch[f],x); 
31           if(tree[v].pri<tree[tree[v].ch[f]].pri) rotate(v,f);
32      }
33 }
34 void del(int &v,int x){
35      if(tree[v].key==x){
36                         if(!tree[v].ch[0]||!tree[v].ch[1]){
37                                                            if(!tree[v].ch[0]) v=tree[v].ch[1];
38                                                            else v=tree[v].ch[0];
39                         }
40                         else{
41                              int f=!(tree[tree[v].ch[0]].pri>tree[tree[v].ch[1]].pri);
42                              rotate(v,f);
43                              tree[v].size--;
44                              del(tree[v].ch[!f],x);
45                         }
46      }
47      else{
48           tree[v].size--;
49           int f=(x<tree[v].key);
50           del(tree[v].ch[!f],x);
51      }
52 }  
53 int find(int v,int x){
54     if(x>tree_size||x<=0) return -1;
55     int mid=1;
56     if(tree[v].ch[0]) mid+=tree[tree[v].ch[0]].size;
57     if(x==mid) return tree[v].key+all;
58     if(x<mid) return find(tree[v].ch[0],x);
59     return find(tree[v].ch[1],x-mid);
60 }
61                 
62 int main()
63 {
64     char opt[2];
65     int k,decans=0;
66     scanf("%d %d",&n,&minn);
67     for(int i=0;i<n;i++){
68             scanf("%s %d",&opt,&k);
69             if(opt[0]==I&&k>=minn){insert(root,k-all);tree_size++;}
70             if(opt[0]==A){all+=k;}
71             if(opt[0]==S){
72                             all-=k;
73                             int tmp;
74                             while((tree_size>0) && ((tmp=find(root,1))<minn)){
75                                                                   tree_size--;
76                                                                   decans++;
77                                                                   del(root,tmp-all);
78                             }
79             }
80             if(opt[0]==F){printf("%d\n",find(root,tree_size+1-k));}
81     }
82     printf("%d\n",decans);
83 
84     return 0;
85 }

 

Noi2004郁闷的出纳员-treap树

标签:using   sum   root   删除   while   and   treap   ota   nod   

原文地址:http://www.cnblogs.com/rdzrdz-acm/p/6511514.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!