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 }

你可能感兴趣的:(T)