SBT专题训练

SBT的资料很多(陈启峰的论文以及下面的blog),在这里就不再叙述:给出下面几道题目以及代码:

http://www.cnblogs.com/reflec94/archive/2011/01/22/1942095.html

 

BZOJ   1208     [HNOI2002]营业额统计 {Insert , pred , succ , find}

View Code
  1 /*
  2 
  3 题目:
  4     最小波动值= min { | 该天以前某一天的营业额-该天的营业额 | }
  5 
  6 分析:
  7     求前驱以及后继与当前的数相减的绝对值的最小值。
  8 
  9 */
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <iostream>
 13 #include <cstdlib>
 14 
 15 using namespace std;
 16 
 17 const int X = 1111111;
 18 
 19 int root,tol,n;
 20 bool use[X] = {0};
 21 
 22 struct node{
 23     int val,l,r,s;
 24     void init(int _val){
 25         l = r = 0;
 26         s = 1;
 27         val = _val;
 28     }
 29 }sbt[X];
 30 
 31 void left_rotate(int &t){
 32     int k = sbt[t].r;
 33     sbt[t].r = sbt[k].l;
 34     sbt[k].l = t;
 35     sbt[k].s = sbt[t].s;
 36     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 37     t = k;
 38 }
 39 
 40 void right_rotate(int &t){
 41     int k = sbt[t].l;
 42     sbt[t].l = sbt[k].r;
 43     sbt[k].r = t;
 44     sbt[k].s = sbt[t].s;
 45     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 46     t = k;
 47 }
 48 
 49 void maintain(int &t,bool ok){
 50     if(!ok){
 51         if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s)
 52             right_rotate(t);
 53         else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].r].s){
 54             left_rotate(sbt[t].l);
 55             right_rotate(t);
 56         }
 57         else return;
 58     }
 59     else{
 60         if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s)
 61             left_rotate(t);
 62         else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].l].s){
 63             right_rotate(sbt[t].r);
 64             left_rotate(t);
 65         }
 66         else return;
 67     }
 68     maintain(sbt[t].l,0);
 69     maintain(sbt[t].r,1);
 70     maintain(t,0);
 71     maintain(t,1);
 72 }
 73 
 74 void insert(int &t,int val){
 75     if(!t){
 76         t = ++tol;
 77         sbt[t].init(val);
 78         return;
 79     }
 80     sbt[t].s++;
 81     if(val<sbt[t].val)
 82         insert(sbt[t].l,val);
 83     else
 84         insert(sbt[t].r,val);
 85     maintain(t,val>=sbt[t].val);
 86 }
 87 
 88 int get_pre(int t,int val){
 89     if(!t)
 90         return val;
 91     if(val<=sbt[t].val)
 92         return get_pre(sbt[t].l,val);
 93     else{
 94         int temp = get_pre(sbt[t].r,val);
 95         return temp==val?sbt[t].val:temp;
 96     }
 97 }
 98 
 99 int get_succ(int t,int val){
100     if(!t)
101         return val;
102     if(val>=sbt[t].val)
103         return get_succ(sbt[t].r,val);
104     else{
105         int temp = get_succ(sbt[t].l,val);
106         return temp==val?sbt[t].val:temp;
107     }
108 }
109 
110 int main(){
111     freopen("sum.in","r",stdin);
112     //freopen("sum.out","w",stdout);
113     root = tol = 0;
114     int ans = 0,x;
115     cin>>n>>x;
116     int qq = 1000000;
117     ans = x;
118     insert(root,x);
119     use[x+qq] = true;
120     int xx,yy;
121     for(int i=1;i<n;i++){
122         if(scanf("%d",&x)==EOF)
123             x = 0;
124         if(use[qq+x])
125             continue;
126         use[qq+x] = true;
127         if(!(xx = x-get_pre(root,x)))
128             xx = X;
129         if(!(yy = get_succ(root,x)-x))
130             yy = X;
131 
132         ans += min(xx,yy);
133         insert(root,x);
134     }
135     cout<<ans<<endl;
136     return 0;
137 }

 

BZOJ   1503     [NOI2004]郁闷的出纳员 {Insert , DeleteSmall , Select}

View Code
  1 /*
  2 
  3 题目:
  4     第一行有两个非负整数n和min。n表示下面有多少条命令,min表示工资下界。
  5     接下来的n行,每行表示一条命令。命令可以是以下四种之一:
  6     I命令(I k): 新建一个工资档案,初始工资为k。如果某员工的初始工资低
  7     于工资下界,他将立刻离开公司。
  8     A命令(A k): 把每位员工的工资加上k
  9     S命令(S k): 把每位员工的工资扣除k
 10     F命令(F k): 查询第k多的工资
 11     一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻
 12     气愤地离开公司,并且再也不会回来了。问现在工资第k多的员工拿多少工资
 13 
 14 分析:
 15     像线段树的lazy标记一样,设置标记delay表示当前为止已经增加了的工资,
 16     若重新来了一名新员工的话,得要把他的工资减掉delay,表示他现在的工资
 17     (因为在delete操作中是SBT中的val值加上delay)。其他的基本如同SBT求
 18     第K大了。
 19 
 20 */
 21 #include <iostream>
 22 #include <cstdio>
 23 #include <cstring>
 24 
 25 using namespace std;
 26 
 27 const int X = 100005;
 28 
 29 int root,tol;
 30 
 31 struct node{
 32     int l,r,val,s;
 33     void init(){
 34         l = r = 0;
 35         s = 1;
 36     }
 37 }sbt[X];
 38 
 39 void left_rotate(int &t){
 40     int k = sbt[t].r;
 41     sbt[t].r = sbt[k].l;
 42     sbt[k].l = t;
 43     sbt[k].s = sbt[t].s;
 44     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 45     t = k;
 46 }
 47 
 48 void right_rotate(int &t){
 49     int k = sbt[t].l;
 50     sbt[t].l = sbt[k].r;
 51     sbt[k].r = t;
 52     sbt[k].s = sbt[t].s;
 53     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 54     t = k;
 55 }
 56 
 57 void maintain(int &t,bool ok){
 58     if(!ok){
 59         if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s)
 60             right_rotate(t);
 61         else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].r].s){
 62             left_rotate(sbt[t].l);
 63             right_rotate(t);
 64         }
 65         else
 66             return;
 67     }
 68     else{
 69         if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s)
 70             left_rotate(t);
 71         else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].l].s){
 72             right_rotate(sbt[t].r);
 73             left_rotate(t);
 74         }
 75         else
 76             return;
 77     }
 78     maintain(sbt[t].l,0);
 79     maintain(sbt[t].r,1);
 80     maintain(t,0);
 81     maintain(t,1);
 82 }
 83 
 84 void insert(int &t,int val){
 85     if(!t){
 86         t = ++tol;
 87         sbt[t].init();
 88         sbt[t].val = val;
 89         return;
 90     }
 91     sbt[t].s++;
 92     if(val<sbt[t].val)
 93         insert(sbt[t].l,val);
 94     else
 95         insert(sbt[t].r,val);
 96     maintain(t,val>=sbt[t].val);
 97 }
 98 
 99 int del(int &t,int val){
100     if(!t)
101         return 0;
102     sbt[t].s--;
103     if(sbt[t].val==val||(val<sbt[t].val&&!sbt[t].l)||(val>sbt[t].val&&!sbt[t].r)){
104         if(sbt[t].l&&sbt[t].r){
105             int pos = del(sbt[t].l,val+1);
106             sbt[t].val = sbt[pos].val;
107             return pos;
108         }
109         else{
110             int pos = t;
111             t = sbt[t].l+sbt[t].r;
112             return pos;
113         }
114     }
115     else
116         return del(val<sbt[t].val?sbt[t].l:sbt[t].r,val);
117 }
118 
119 void Delete(int &t,int delay,int min_val){
120     if(!t)
121         return;
122     if(sbt[t].val+delay<min_val){
123         t = sbt[t].r;
124         Delete(t,delay,min_val);
125     }
126     else{
127         Delete(sbt[t].l,delay,min_val);
128         sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
129     }
130 }
131 
132 int find_k(int &t,int k){
133     if(k<=sbt[sbt[t].l].s)
134         return find_k(sbt[t].l,k);
135     else if(k>sbt[sbt[t].l].s+1)
136         return find_k(sbt[t].r,k-sbt[sbt[t].l].s-1);
137     else
138         return sbt[t].val;
139 }
140 
141 int find_k_max(int &t,int k){
142     if(k<=sbt[sbt[t].r].s)
143         return find_k_max(sbt[t].r,k);
144     else if(k>sbt[sbt[t].r].s+1)
145         return find_k_max(sbt[t].l,k-sbt[sbt[t].r].s-1);
146     else
147         return sbt[t].val;
148 }
149 
150 int get_rank(int &t,int val){
151     if(val<sbt[t].val)
152         return get_rank(sbt[t].l,val);
153     else if(val>sbt[t].val)
154         return get_rank(sbt[t].r,val)+sbt[sbt[t].l].s+1;
155     else
156         return sbt[sbt[t].l].s+1;
157 }
158 
159 void inorder(int &t){
160     if(!t)
161         return;
162     inorder(sbt[t].l);
163     printf("%d\n",sbt[t].val);
164     inorder(sbt[t].r);
165 }
166 
167 int get_min(int &t){
168     while(sbt[t].l)
169         t = sbt[t].l;
170     return t;
171 }
172 
173 int get_max(int &t){
174     while(sbt[t].r)
175         t = sbt[t].r;
176     return t;
177 }
178 
179 int main(){
180     freopen("sum.in","r",stdin);
181     int x;
182     int n,min_val,delay;
183     char str[5];
184     while(cin>>n>>min_val){
185         root = delay = tol = 0;
186         while(n--){
187             scanf("%s%d",str,&x);
188             if(str[0]=='I'){
189                 if(x<min_val)
190                     continue;
191                 insert(root,x-delay);
192             }
193             else if(str[0]=='A')
194                 delay += x;
195             else if(str[0]=='S'){
196                 delay -= x;
197                 Delete(root,delay,min_val);
198             }
199             else
200                 printf("%d\n",sbt[root].s>=x?find_k_max(root,x)+delay:-1);
201         }
202         printf("%d\n",tol-sbt[root].s);
203     }
204     return 0;
205 }

 

BZOJ   1588     [HNOI2004]宠物收养所 {Insert , pred , succ , Delete}

View Code
  1 /*
  2 
  3 分析:
  4     SBT功能的应用:删除、前驱、后继
  5     这题就是简单的元素插入删除操作,注意一下绝对值相同的时候取较小的即可,
  6     还有就是每次收养所里要么都是人,要么都是宠物。
  7     当树种相同的时候,直接插入SBT中,当树种不一样的时候,从SBT中找到满足条
  8     件的前驱或者后继,更新答案后在SBT中删除该值即可
  9 
 10 */
 11 #include <iostream>
 12 #include <cstdio>
 13 #include <cstring>
 14 
 15 using namespace std;
 16 
 17 const int X = 1000005;
 18 const long long mod = 1000000;
 19 #define debug puts("here");
 20 
 21 int root,tol;
 22 
 23 struct node{
 24     int l,r,s,val;
 25     void init(int _val){
 26         l = r = 0;
 27         s = 1;
 28         val = _val;
 29     }
 30 }sbt[X];
 31 
 32 void left_rotate(int &t){
 33     int k = sbt[t].r;
 34     sbt[t].r = sbt[k].l;
 35     sbt[k].l = t;
 36     sbt[k].s = sbt[t].s;
 37     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 38     t = k;
 39 }
 40 
 41 void right_rotate(int &t){
 42     int k = sbt[t].l;
 43     sbt[t].l = sbt[k].r;
 44     sbt[k].r = t;
 45     sbt[k].s = sbt[t].s;
 46     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 47     t = k;
 48 }
 49 
 50 void maintain(int &t,bool ok){
 51     if(!ok){
 52         if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s)
 53             right_rotate(t);
 54         else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].l].s){
 55             left_rotate(sbt[t].l);
 56             right_rotate(t);
 57         }
 58         else return;
 59     }
 60     else{
 61         if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s)
 62             left_rotate(t);
 63         else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].l].s){
 64             right_rotate(sbt[t].r);
 65             left_rotate(t);
 66         }
 67         else return;
 68     }
 69     maintain(sbt[t].l,0);
 70     maintain(sbt[t].r,1);
 71     maintain(t,0);
 72     maintain(t,1);
 73 }
 74 
 75 void insert(int &t,int val){
 76     if(!t){
 77         t = ++tol;
 78         sbt[t].init(val);
 79         return;
 80     }
 81     sbt[t].s++;
 82     if(val<sbt[t].val)
 83         insert(sbt[t].l,val);
 84     else
 85         insert(sbt[t].r,val);
 86     maintain(t,val>=sbt[t].val);
 87 }
 88 
 89 int del(int &t,int val){
 90     if(!t)  return 0;
 91     sbt[t].s--;
 92     if(val==sbt[t].val||(val<sbt[t].val&&!sbt[t].l)||(val>sbt[t].val&&!sbt[t].r)){
 93         if(sbt[t].l&&sbt[t].r){
 94             int pos = del(sbt[t].l,val+1);
 95             sbt[t].val = sbt[pos].val;
 96             return pos;
 97         }
 98         else{
 99             int pos = t;
100             t = sbt[t].l+sbt[t].r;
101             return pos;
102         }
103     }
104     return del(val<sbt[t].val?sbt[t].l:sbt[t].r,val);
105 }
106 
107 int get_pre(int t,int val){
108     if(!t)  return val;
109     if(val<=sbt[t].val)
110         return get_pre(sbt[t].l,val);
111     else{
112         int temp = get_pre(sbt[t].r,val);
113         return temp==val?sbt[t].val:temp;
114     }
115 }
116 
117 int get_succ(int t,int val){
118     if(!t)  return val;
119     if(val>=sbt[t].val)
120         return get_succ(sbt[t].r,val);
121     else{
122         int temp = get_succ(sbt[t].l,val);
123         return val==temp?sbt[t].val:temp;
124     }
125 }
126 
127 int main(){
128     freopen("sum.in","r",stdin);
129     int n,x,y,pre,succ,op,val;
130     while(cin>>n){
131         long long ans = 0;
132         root = tol = 0;
133         int sum  = 0,kind = 0;
134         for(int i=0;i<n;i++){
135             scanf("%d%d",&op,&val);
136             if(!sum||kind==op){
137                 kind = op;
138                 insert(root,val);
139                 sum++;
140             }
141             else{
142                 pre = get_pre(root,val);
143                 succ = get_succ(root,val);
144                 x = val-pre;
145                 y = succ-val;
146                 sum--;
147                 if(!x){
148                     ans = (ans+y)%mod;
149                     del(root,succ);
150                     continue;
151                 }
152                 if(!y){
153                     ans = (ans+x)%mod;
154                     del(root,pre);
155                     continue;
156                 }
157                 if(x<=y){
158                     ans = (ans+x)%mod;
159                     del(root,pre);
160                 }
161                 else{
162                     ans = (ans+y)%mod;
163                     del(root,succ);
164                 }
165             }
166         }
167         cout<<ans<<endl;
168     }
169     return 0;
170 }

 

poj      3481     Double Queue {Insert , DeleteMax , DeleteMin}

View Code
  1 /*
  2 
  3 题目:
  4     三种操作:
  5     0    The system needs to stop serving
  6     1 K P    Add client K to the waiting list with priority P
  7     2    Serve the client with the highest priority and drop him or her from the waiting list
  8     3    Serve the client with the lowest priority and drop him or her from the waiting list
  9     问出队序列
 10 
 11 分析:
 12     2号操作的时候,直接搜索右子树的最右儿子的val域
 13     3号操作的时候,直接搜索左子树的最左儿子的val域
 14 
 15 */
 16 #include <iostream>
 17 #include <cstdio>
 18 #include <cstring>
 19 
 20 using namespace std;
 21 
 22 const int X = 1e6+5;
 23 
 24 int root,tol;
 25 
 26 struct node{
 27     int l,r,s,id,val;
 28     void init(int _val,int _id){
 29         l = r = 0;
 30         s = 1;
 31         val = _val;
 32         id = _id;
 33     }
 34 }sbt[X];
 35 
 36 void left_rotate(int &t){
 37     int k = sbt[t].r;
 38     sbt[t].r = sbt[k].l;
 39     sbt[k].l = t;
 40     sbt[k].s = sbt[t].s;
 41     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 42     t = k;
 43 }
 44 
 45 void right_rotate(int &t){
 46     int k = sbt[t].l;
 47     sbt[t].l = sbt[k].r;
 48     sbt[k].r = t;
 49     sbt[k].s = sbt[t].s;
 50     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 51     t = k;
 52 }
 53 
 54 void maintain(int &t,bool ok){
 55     if(!ok){
 56         if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s)
 57             right_rotate(t);
 58         else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].r].s){
 59             left_rotate(sbt[t].l);
 60             right_rotate(t);
 61         }
 62         else return;
 63     }
 64     else{
 65         if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s)
 66             left_rotate(t);
 67         else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].l].s){
 68             right_rotate(sbt[t].r);
 69             left_rotate(t);
 70         }
 71         else return;
 72     }
 73     maintain(sbt[t].l,0);
 74     maintain(sbt[t].r,1);
 75     maintain(t,0);
 76     maintain(t,1);
 77 }
 78 
 79 void insert(int &t,int val,int id){
 80     if(!t){
 81         t = ++tol;
 82         sbt[t].init(val,id);
 83         return;
 84     }
 85     sbt[t].s++;
 86     if(val<sbt[t].val)
 87         insert(sbt[t].l,val,id);
 88     else
 89         insert(sbt[t].r,val,id);
 90     maintain(t,val>=sbt[t].val);
 91 }
 92 
 93 int del(int &t,int val){
 94     if(!t)  return 0;
 95     sbt[t].s--;
 96     if(val==sbt[t].val||(val<sbt[t].val&&!sbt[t].l)||(val>sbt[t].val&&!sbt[t].r)){
 97         if(sbt[t].l&&sbt[t].r){
 98             int pos = del(sbt[t].l,val+1);
 99             sbt[t].val = sbt[pos].val;
100             return pos;
101         }
102         else{
103             int pos = t;
104             t = sbt[t].l+sbt[t].r;
105             return pos;
106         }
107     }
108     else
109         return del(val<sbt[t].val?sbt[t].l:sbt[t].r,val);
110 }
111 
112 int _val;
113 
114 int get_min(int t){
115     while(sbt[t].l)
116         t = sbt[t].l;
117     _val = sbt[t].val;
118     return sbt[t].id;
119 }
120 
121 int get_max(int t){
122     while(sbt[t].r)
123         t = sbt[t].r;
124     _val = sbt[t].val;
125     return sbt[t].id;
126 }
127 
128 int main()
129 {
130     freopen("aum.in","r",stdin);
131     int op,val,id,temp;
132     root = tol = 0;
133     while(scanf("%d",&op),op){
134         if(op==1){
135             scanf("%d%d",&id,&val);
136             insert(root,val,id);
137         }
138         else if(op==2){
139             temp = get_max(root);
140             printf("%d\n",temp);
141             del(root,_val);
142         }
143         else{
144             temp = get_min(root);
145             printf("%d\n",temp);
146             del(root,_val);
147         }
148     }
149     return 0;
150 }

 

poj      2892     Tunnel Warfare 

View Code
  1 /*
  2 
  3 题目:
  4     现有n座城堡在一直线上,除了两端之外,其余的都各自与相邻的城堡有道路,
  5     现在有三种操作,摧毁城堡,修复城堡,询问城堡x与他相连的城堡数目(包括
  6     自己)。
  7 
  8 分析:
  9     SBT,每当摧毁城堡的时候插入一个节点,当询问的时候,查找比栈顶元素小的
 10     以及大的位置,两者相减再减一。
 11 
 12 */
 13 #include <cstdio>
 14 #include <cstring>
 15 #include <iostream>
 16 
 17 using namespace std;
 18 
 19 const int X = 200005;
 20 #define debug puts("here");
 21 
 22 int n,m;
 23 int s[X],top;
 24 int use[X];
 25 int root,tol;
 26 
 27 struct node{
 28     int l,r,val,s;
 29     void init(){
 30         l = r = 0;
 31         s = 1;
 32     }
 33 }sbt[X];
 34 
 35 void left_rotate(int &t){
 36     int k = sbt[t].r;
 37     sbt[t].r = sbt[k].l;
 38     sbt[k].l = t;
 39     sbt[k].s = sbt[t].s;
 40     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 41     t = k;
 42 }
 43 
 44 void right_rotate(int &t){
 45     int k = sbt[t].l;
 46     sbt[t].l = sbt[k].r;
 47     sbt[k].r = t;
 48     sbt[k].s = sbt[t].s;
 49     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 50     t = k;
 51 }
 52 
 53 void maintain(int &t,bool ok){
 54     if(!ok){
 55         if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s)
 56             right_rotate(t);
 57         else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].r].s){
 58             left_rotate(sbt[t].l);
 59             right_rotate(t);
 60         }
 61         else
 62             return;
 63     }
 64     else{
 65         if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s)
 66             left_rotate(t);
 67         else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].l].s){
 68             right_rotate(sbt[t].r);
 69             left_rotate(t);
 70         }
 71         else
 72             return;
 73     }
 74     maintain(sbt[t].l,0);
 75     maintain(sbt[t].r,1);
 76     maintain(t,0);
 77     maintain(t,1);
 78 }
 79 
 80 void insert(int &t,int val){
 81     if(!t){
 82         t = ++tol;
 83         sbt[t].init();
 84         sbt[t].val = val;
 85     }
 86     else{
 87         sbt[t].s++;
 88         if(val<sbt[t].val)
 89             insert(sbt[t].l,val);
 90         else
 91             insert(sbt[t].r,val);
 92         maintain(t,val>=sbt[t].val);
 93     }
 94 }
 95 
 96 int del(int &t,int val){
 97     if(!t)
 98         return 0;
 99     sbt[t].s--;
100     if(val==sbt[t].val||(val<sbt[t].val&&!sbt[t].l)||(val>sbt[t].val&&!sbt[t].r)){
101         if(sbt[t].l&&sbt[t].r){
102             int pos = del(sbt[t].l,val+1);
103             sbt[t].val = sbt[pos].val;
104             return pos;
105         }
106         else{
107             int pos = t;
108             t = sbt[t].l+sbt[t].r;
109             return pos;
110         }
111     }
112     else
113         return del(val<sbt[t].val?sbt[t].l:sbt[t].r,val);
114 }
115 
116 int less_than(int t,int val){
117     if(!t)
118         return 0;
119     if(val<sbt[t].val)
120         return less_than(sbt[t].l,val);
121     else
122         return max(sbt[t].val,less_than(sbt[t].r,val));
123 }
124 
125 int greater_than(int t,int val){
126     if(!t)
127         return n+1;
128     if(val>sbt[t].val)
129         return greater_than(sbt[t].r,val);
130     else
131         return min(sbt[t].val,greater_than(sbt[t].l,val));
132 }
133 
134 int main(){
135     freopen("sum.in","r",stdin);
136     char str[5];
137     int x;
138     while(cin>>n>>m){
139         for(int i=0;i<=X;i++)
140             sbt[i].init();
141         memset(use,0,sizeof(use));
142         top = 0;
143         root = 0;
144         tol = 0;
145         while(m--){
146             scanf("%s",str);
147             if(str[0]=='D'){
148                 scanf("%d",&x);
149                 use[x]++;
150                 s[++top] = x;
151                 insert(root,x);
152             }
153             else if(str[0]=='R'){
154                 if(top>0){
155                     del(root,s[top]);
156                     use[s[top--]]--;
157                 }
158             }
159             else{
160                 scanf("%d",&x);
161                 if(use[x])
162                     puts("0");
163                 else{
164                     int r = greater_than(root,x);
165                     int l = less_than(root,x);
166                     //cout<<r<<" "<<l<<" ";
167                     printf("%d\n",r-l-1);
168                 }
169             }
170         }
171     }
172     return 0;
173 }

 

解决约瑟夫环问题:

ural      1521      War Games 2   

View Code
  1 /*
  2 
  3 ural 1521
  4 http://ac.jobdu.com/problem.php?pid=1188
  5 题目1188:约瑟夫环
  6 题目描述:
  7 N个人围成一圈顺序编号,从1号开始按1、2、3......顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。
  8 请按退出顺序输出每个退出人的原序号。
  9 
 10 输入:
 11 包括一个整数N(1<=N<=3000)及一个整数p。
 12 
 13 输出:
 14 测试数据可能有多组,对于每一组数据,
 15 按退出顺序输出每个退出人的原序号。
 16 
 17 样例输入:
 18 7 3
 19 样例输出:
 20 3 6 2 7 5 1 4
 21 
 22 */
 23 
 24 /*
 25 
 26 分析:
 27     先把所有人插入到SBT中,然后出去的时候,把他从SBT中删除,而找到要删除的
 28     元素为pos = (pre+k-1)%n+1,n每出去一个人减一,而pre从0开始,若已经有人
 29     出队,则置为上一个人出队的位置减一,然后就是找到第pos小即可
 30 
 31 */
 32 
 33 #include <iostream>
 34 #include <cstdio>
 35 #include <cstring>
 36 
 37 using namespace std;
 38 
 39 const int X = 100005;
 40 
 41 int root,tol,n,m;
 42 
 43 struct node{
 44     int val,l,r,s;
 45     void init(int _val){
 46         l = r = 0;
 47         s = 1;
 48         val = _val;
 49     }
 50 }sbt[X];
 51 
 52 void left_rotate(int &t){
 53     int k = sbt[t].r;
 54     sbt[t].r = sbt[k].l;
 55     sbt[k].l = t;
 56     sbt[k].s = sbt[t].s;
 57     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 58     t = k;
 59 }
 60 
 61 void right_rotate(int &t){
 62     int k = sbt[t].l;
 63     sbt[t].l = sbt[k].r;
 64     sbt[k].r = t;
 65     sbt[k].s = sbt[t].s;
 66     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 67     t = k;
 68 }
 69 
 70 void maintain(int &t,bool ok){
 71     if(!ok){
 72         if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s)
 73             right_rotate(t);
 74         else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].r].s){
 75             left_rotate(sbt[t].l);
 76             right_rotate(t);
 77         }
 78         else return;
 79     }
 80     else{
 81         if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s)
 82             left_rotate(t);
 83         else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].l].s){
 84             right_rotate(sbt[t].r);
 85             left_rotate(t);
 86         }
 87         else return;
 88     }
 89     maintain(sbt[t].l,0);
 90     maintain(sbt[t].r,1);
 91     maintain(t,0);
 92     maintain(t,1);
 93 }
 94 
 95 void insert(int &t,int val){
 96     if(!t){
 97         t = ++tol;
 98         sbt[t].init(val);
 99         return;
100     }
101     sbt[t].s++;
102     if(val<sbt[t].val)
103         insert(sbt[t].l,val);
104     else
105         insert(sbt[t].r,val);
106     maintain(t,val>=sbt[t].val);
107 }
108 
109 int del(int &t,int val){
110     if(!t)  return 0;
111     sbt[t].s--;
112     if(val==sbt[t].val||(val<sbt[t].val&&!sbt[t].l)||(val>sbt[t].val&&!sbt[t].r)){
113         if(sbt[t].l&&sbt[t].r){
114             int pos = del(sbt[t].l,val+1);
115             sbt[t].val = sbt[pos].val;
116             return pos;
117         }
118         else{
119             int pos = t;
120             t = sbt[t].l+sbt[t].r;
121             return pos;
122         }
123     }
124     else
125         return del(val<sbt[t].val?sbt[t].l:sbt[t].r,val);
126 }
127 
128 int find_k_min(int &t,int k){   //找到第k小
129     if(k<=sbt[sbt[t].l].s)
130         return find_k_min(sbt[t].l,k);
131     else if(k>sbt[sbt[t].l].s+1)
132         return find_k_min(sbt[t].r,k-sbt[sbt[t].l].s-1);
133     else
134         return sbt[t].val;
135 }
136 
137 int main()
138 {
139     freopen("sum.in","r",stdin);
140     freopen("sum.out","w",stdout);
141     while(cin>>n>>m){
142         int pos = 0,temp,val;
143         root = tol = 0;
144         for(int i=1;i<=n;i++)
145             insert(root,i);
146         while(n){
147             temp = (pos+m-1)%n+1;
148             pos = temp-1;
149             val = find_k_min(root,temp);
150             del(root,val);
151             printf("%d",val);
152             if(n>1)
153                 putchar(' ');
154             n--;
155         }
156         puts("");
157     }
158     return 0;
159 }

 

poj       3750        小孩报数问题(跟上面一题基本一样)

View Code
  1 /*
  2 
  3 题目:
  4     约瑟夫环
  5 
  6 */
  7 #include <iostream>
  8 #include <cstdio>
  9 #include <cstring>
 10 
 11 using namespace std;
 12 
 13 const int X = 100;
 14 
 15 char str[X][20];
 16 int n;
 17 int root,tol;
 18 
 19 struct node{
 20     int l,r,val,s;
 21     void init(){
 22         l = r = 0;
 23         s = 1;
 24     }
 25 }sbt[X];
 26 
 27 void left_rotate(int &t){
 28     int k = sbt[t].r;
 29     sbt[t].r = sbt[k].l;
 30     sbt[k].l = t;
 31     sbt[k].s = sbt[t].s;
 32     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 33     t = k;
 34 }
 35 
 36 void right_rotate(int &t){
 37     int k = sbt[t].l;
 38     sbt[t].l = sbt[k].r;
 39     sbt[k].r = t;
 40     sbt[k].s = sbt[t].s;
 41     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 42     t = k;
 43 }
 44 
 45 void maintain(int &t,bool ok){
 46     if(!ok){
 47         if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s)
 48             right_rotate(t);
 49         else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].r].s){
 50             left_rotate(sbt[t].l);
 51             right_rotate(t);
 52         }
 53         else
 54             return;
 55     }
 56     else{
 57         if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s)
 58             left_rotate(t);
 59         else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].r].s){
 60             right_rotate(sbt[t].r);
 61             left_rotate(t);
 62         }
 63         else
 64             return;
 65     }
 66     maintain(sbt[t].l,0);
 67     maintain(sbt[t].r,1);
 68     maintain(t,0);
 69     maintain(t,1);
 70 }
 71 
 72 void insert(int &t,int val){
 73     if(!t){
 74         t = ++tol;
 75         sbt[t].init();
 76         sbt[t].val = val;
 77         return;
 78     }
 79     sbt[t].s++;
 80     if(val<sbt[t].val)
 81         insert(sbt[t].l,val);
 82     else
 83         insert(sbt[t].r,val);
 84     maintain(t,val>=sbt[t].val);
 85 }
 86 
 87 int del(int &t,int val){
 88     if(!t)
 89         return 0;
 90     sbt[t].s--;
 91     if(sbt[t].val==val||(val<sbt[t].val&&!sbt[t].l)||(val>sbt[t].val&&!sbt[t].r)){
 92         if(sbt[t].l&&sbt[t].r){
 93             int pos = del(sbt[t].l,val+1);
 94             sbt[t].val = sbt[pos].val;
 95             return pos;
 96         }
 97         else{
 98             int pos = t;
 99             t = sbt[t].l+sbt[t].r;
100             return pos;
101         }
102     }
103     else
104         return del(val<sbt[t].val?sbt[t].l:sbt[t].r,val);
105 }
106 
107 int find_k_min(int &t,int k){   //找到第k小
108     if(k<=sbt[sbt[t].l].s)
109         return find_k_min(sbt[t].l,k);
110     else if(k>sbt[sbt[t].l].s+1)
111         return find_k_min(sbt[t].r,k-sbt[sbt[t].l].s-1);
112     else
113         return sbt[t].val;
114 }
115 
116 int main(){
117     freopen("sum.in","r",stdin);
118     int x,y;
119     while(cin>>n){
120         tol = root = 0;
121         for(int i=1;i<=n;i++){
122             scanf("%s",str[i]);
123             insert(root,i);
124         }
125         scanf("%d,%d",&x,&y);
126         x--;
127         while(n){
128             int temp = (x+y-1)%n+1;
129             x = temp-1;
130             temp = find_k_min(root,temp);
131             printf("%s\n",str[temp]);
132             del(root,temp);
133             n--;
134         }
135     }
136     return 0;
137 }

 

poj        3517        And Then There Was One

View Code
  1 /*
  2 
  3 题目:
  4     约瑟夫环问题,问最后只剩下的元素
  5 
  6 */
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <iostream>
 10 
 11 using namespace std;
 12 
 13 const int X = 100005;
 14 #define debug puts("here");
 15 
 16 int tol,root;
 17 
 18 struct node{
 19     int l,r,val,s;
 20     void init(int _val){
 21         l = r = 0;
 22         s = 1;
 23         val = _val;
 24     }
 25 }sbt[X];
 26 
 27 void left_rotate(int &t){
 28     int k = sbt[t].r;
 29     sbt[t].r = sbt[k].l;
 30     sbt[k].l = t;
 31     sbt[k].s = sbt[t].s;
 32     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 33     t = k;
 34 }
 35 
 36 void right_rotate(int &t){
 37     int k = sbt[t].l;
 38     sbt[t].l = sbt[k].r;
 39     sbt[k].r = t;
 40     sbt[k].s = sbt[t].s;
 41     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 42     t = k;
 43 }
 44 
 45 void maintain(int &t,bool ok){
 46     if(!ok){
 47         if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s)
 48             right_rotate(t);
 49         else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].r].s){
 50             left_rotate(sbt[t].l);
 51             right_rotate(t);
 52         }
 53         else return;
 54     }
 55     else{
 56         if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s)
 57             left_rotate(t);
 58         else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].l].s){
 59             right_rotate(sbt[t].r);
 60             left_rotate(t);
 61         }
 62         else return;
 63     }
 64     maintain(sbt[t].l,0);
 65     maintain(sbt[t].r,1);
 66     maintain(t,0);
 67     maintain(t,1);
 68 }
 69 
 70 void insert(int &t,int val){
 71     if(!t){
 72         t = ++tol;
 73         sbt[t].init(val);
 74         return;
 75     }
 76     sbt[t].s++;
 77     if(val<sbt[t].val)
 78         insert(sbt[t].l,val);
 79     else
 80         insert(sbt[t].r,val);
 81     maintain(t,val>=sbt[t].val);
 82 }
 83 
 84 int del(int &t,int val){
 85     if(!t)  return 0;
 86     sbt[t].s--;
 87     if(sbt[t].val==val||(val<sbt[t].val&&!sbt[t].l)||(val>sbt[t].val&&!sbt[t].r)){
 88         if(sbt[t].l&&sbt[t].r){
 89             int pos = del(sbt[t].l,val+1);
 90             sbt[t].val = sbt[pos].val;
 91             return pos;
 92         }
 93         else{
 94             int pos = t;
 95             t = sbt[t].l+sbt[t].r;
 96             return pos;
 97         }
 98     }
 99     else
100         return del(val<sbt[t].val?sbt[t].l:sbt[t].r,val);
101 }
102 
103 int find_k_min(int &t,int k){
104     if(k<=sbt[sbt[t].l].s)
105         return find_k_min(sbt[t].l,k);
106     else if(k>sbt[sbt[t].l].s+1)
107         return find_k_min(sbt[t].r,k-sbt[sbt[t].l].s-1);
108     return sbt[t].val;
109 }
110 
111 int find_k_max(int &t,int k){
112     if(k<sbt[sbt[t].r].s)
113         return find_k_max(sbt[t].r,k);
114     else if(k>sbt[sbt[t].r].s+1)
115         return find_k_max(sbt[t].l,k-sbt[sbt[t].r].s-1);
116     return sbt[t].val;
117 }
118 
119 int get_pre(int &t,int val){
120     if(!t)  return 0;
121     if(val<sbt[t].val)
122         return get_pre(sbt[t].l,val);
123     else
124         return max(sbt[t].val,get_pre(sbt[t].r,val));
125 }
126 
127 int get_next(int &t,int val){
128     if(!t)  return 0;
129     if(val>sbt[t].val)
130         return get_next(sbt[t].r,val);
131     else
132         return min(sbt[t].val,get_next(sbt[t].l,val));
133 }
134 
135 int get_rank(int &t,int val){
136     if(val<sbt[t].val)
137         return get_rank(sbt[t].l,val);
138     else if(val>sbt[t].val)
139         return get_rank(sbt[t].r,val)+sbt[sbt[t].l].s+1;
140     else
141         return sbt[sbt[t].l].s+1;
142 }
143 
144 int main(){
145     freopen("sum.in","r",stdin);
146     int n,k,s;
147     while(cin>>n>>k>>s,n||k||s){
148         if(n==1){
149             puts("1");
150             continue;
151         }
152         root = tol = 0;
153         for(int i=1;i<=n;i++)
154             insert(root,i);
155         int pos = s+n-k;
156         while(n){
157             int temp = (pos+k-1)%n+1;
158             pos = temp-1;
159             temp = find_k_min(root,temp);
160             del(root,temp);
161             if(n==2){
162                 printf("%d\n",find_k_min(root,1));
163                 break;
164             }
165             n--;
166         }
167     }
168     return 0;
169 }

转载于:https://www.cnblogs.com/yejinru/archive/2012/09/01/2666645.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值