• 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 }
  • 相关阅读:
    Java 注解
    java 编码设计细节
    快捷键大全
    java 常用方法
    用SelectSingleNode()方法查找xml节点一直返回null
    未能加载文件或程序集“microsoft.Build.Engine, Version=3.5.0.0,...”或它的摸一个依赖项。
    引用dll出现了黄色感叹号
    保持控件和容器之间的相对位置
    DataGridView中EnditCommit()调用之后,单元格的内容被全选了,每次输入都要鼠标点击定位到最后才能继续输入
    访问DataGridView的Rows报了OutOfIndexRangeException错误
  • 原文地址:https://www.cnblogs.com/yejinru/p/2666645.html
Copyright © 2020-2023  润新知