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

bzoj3224 普通平衡树

时间:2015-02-09 20:12:32      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

 

这道题我先写了值域线段树,一直WA,和网上的标程对拍,也拍不出错误,然后改写SPALY,又WA,也拍不出错误,最后只能用vector水过了。

我把我写的值域线段树、Splay、vector、数据生成器放在下面,若有哪位好心人愿意帮我看看,感激不尽。

 

 

值域线段树:

技术分享
  1 /**************************************************************
  2 Problem: 3224
  3 User: idy002
  4 Language: C++
  5 Result: Wrong_Answer
  6  ****************************************************************/
  7 
  8 #include <cstdio>
  9 #define fprintf(...)
 10 #define maxn 7000000
 11 #define minv 0
 12 #define inc 10000000
 13 #define maxv 20000000
 14 
 15 int son[maxn][2], siz[maxn], ntot;
 16 
 17 int newnode() {
 18     int nd = ++ntot;
 19     son[nd][0] = son[nd][1] = siz[nd] = 0;
 20     return nd;
 21 }
 22 void pushup( int nd ) {
 23     siz[nd] = siz[son[nd][0]]+siz[son[nd][1]];
 24 }
 25 void insert( int v, int nd, int lf, int rg ) {
 26     fprintf( stderr, "insert( %d %d %d %d )\n", v, nd, lf, rg );
 27     if( lf==rg ) {
 28         siz[nd]++;
 29         return;
 30     }
 31     int mid = (lf+rg)>>1;
 32     if( !son[nd][ v>mid ] ) son[nd][ v>mid ] = newnode();
 33     if( v<=mid ) insert( v, son[nd][0], lf, mid );
 34     else insert( v, son[nd][1], mid+1, rg );
 35     pushup(nd);
 36 }
 37 void erase( int v, int nd, int lf, int rg ) {
 38     fprintf( stderr, "erase( %d %d %d %d )\n", v, nd, lf, rg );
 39     if( lf==rg ) {
 40         siz[nd]--;
 41         return;
 42     }
 43     int mid = (lf+rg)>>1;
 44     if( v<=mid ) erase( v, son[nd][0], lf, mid );
 45     else erase( v, son[nd][1], mid+1, rg );
 46     pushup(nd);
 47 }
 48 int rank( int v, int nd, int lf, int rg ) {
 49     fprintf( stderr, "rank( %d %d %d %d )\n", v, nd, lf, rg );
 50     if( lf==rg ) return 1;
 51     int mid = (lf+rg)>>1;
 52     if( v<=mid ) return rank(v,son[nd][0],lf,mid);
 53     else return siz[son[nd][0]]+rank(v,son[nd][1],mid+1,rg);
 54 }
 55 int nth( int n, int nd, int lf, int rg ) {
 56     fprintf( stderr, "nth( %d %d %d %d )\n", n, nd, lf, rg );
 57     if( lf==rg ) return lf;
 58     int ls = siz[son[nd][0]];
 59     int mid = (lf+rg)>>1;
 60     if( n<=ls ) return nth(n,son[nd][0],lf,mid);
 61     else return nth(n-ls,son[nd][1],mid+1,rg);
 62 }
 63 int gnext( int v, int nd, int lf, int rg ) {
 64     fprintf( stderr, "gnext( %d %d %d %d )\n", v, nd, lf, rg );
 65     if( !nd ) return v;
 66     if( lf==rg ) return lf>v ? lf : v;
 67     int mid = (lf+rg)>>1;
 68     if( v<=mid ) {
 69         int rt = gnext( v, son[nd][0], lf, mid );
 70         if( rt==v ) return gnext( v, son[nd][1], mid+1, rg );
 71         else return rt;
 72     } 
 73     return gnext( v, son[nd][1], mid+1, rg );
 74 }
 75 int gprev( int v, int nd, int lf, int rg ) {
 76     fprintf( stderr, "gprev( %d %d %d %d )\n", v, nd, lf, rg );
 77     if( !nd ) return v;
 78     if( lf==rg ) return lf<v ? lf : v;
 79     int mid = (lf+rg)>>1;
 80     if( v>mid ) {
 81         int rt = gprev( v, son[nd][1], mid+1, rg );
 82         if( rt==v ) return gprev( v, son[nd][0], lf, mid );
 83         else return rt;
 84     }
 85     return gprev( v, son[nd][0], lf, mid );
 86 }
 87 
 88 int n;
 89 
 90 int main() {
 91     scanf( "%d", &n );
 92     newnode();
 93     for( int i=1,opt,x; i<=n; i++ ) {
 94         scanf( "%d%d", &opt, &x );
 95         x += inc;
 96         switch(opt) {
 97             case 1:
 98                 insert( x, 1, minv, maxv );
 99                 break;
100             case 2:
101                 erase( x, 1, minv, maxv );
102                 break;
103             case 3:
104                 printf( "%d\n", rank(x,1,minv,maxv) );
105                 break;
106             case 4:
107                 printf( "%d\n", nth(x-inc,1,minv,maxv)-inc );
108                 break;
109             case 5:
110                 printf( "%d\n", gprev(x,1,minv,maxv)-inc );
111                 break;
112             case 6:
113                 printf( "%d\n", gnext(x,1,minv,maxv)-inc );
114                 break;
115         }
116     }
117 }
View Code

splay:

技术分享
  1 #include <cstdio>
  2 #include <iostream>
  3 #define maxn 100020
  4 using namespace std;
  5 
  6 
  7 struct Splay {
  8     int key[maxn], pre[maxn], son[maxn][2], siz[maxn], cnt[maxn], root, ntot;
  9 
 10     int newnode( int k, int p ) {
 11         int nd = ++ntot;
 12         key[nd] = k;
 13         pre[nd] = p;
 14         son[nd][0] = son[nd][1] = 0;
 15         siz[nd] = cnt[nd] = 1;
 16         return nd;
 17     }
 18     void update( int nd ) {
 19         siz[nd] = siz[son[nd][0]] + siz[son[nd][1]] + cnt[nd];
 20     }
 21     void rotate( int nd, int d ) {
 22         int p = pre[nd];
 23         int s = son[nd][!d];
 24         int ss = son[s][d];
 25 
 26         son[nd][!d] = ss;
 27         son[s][d] = nd;
 28         if( p ) son[p][ nd==son[p][1] ] = s;
 29         else root = s;
 30 
 31         pre[nd] = s;
 32         pre[s] = p;
 33         if( ss ) pre[ss] = nd;
 34 
 35         update(nd);
 36         update(s);
 37     }
 38     void splay( int nd, int top ) {
 39         while( pre[nd]!=top ) {
 40             int p = pre[nd];
 41             int nl = nd==son[p][0];
 42             if( pre[p]==top ) {
 43                 rotate( p, nl );
 44             } else {
 45                 int pp = pre[p];
 46                 int pl = p==son[pp][0];
 47                 if( nl==pl ) {
 48                     rotate( pp, pl );
 49                     rotate( p, nl );
 50                 } else {
 51                     rotate( p, nl );
 52                     rotate( pp, pl );
 53                 }
 54             }
 55         }
 56     }
 57     void insert( int k ) {
 58         if( !root ) {
 59             root = newnode( k, 0 );
 60             return;
 61         }
 62         int nd = root;
 63         while( 1 ) {
 64             if( k==key[nd] ) {
 65                 cnt[nd]++;
 66                 break;
 67             } else {
 68                 if( !son[nd][ k>key[nd] ] ) {
 69                     son[nd][ k>key[nd] ] = newnode( k, nd );
 70                     break;
 71                 } 
 72                 nd = son[nd][ k>key[nd] ];
 73             }
 74         }
 75         update( nd );
 76         splay( nd, 0 );
 77     }
 78     int find( int k ) {
 79         int nd = root;
 80         while( 1 ) {
 81             if( k!=key[nd] ) nd = son[nd][ k>key[nd] ];
 82             else break;
 83         }
 84         return nd;
 85     }
 86     void erase( int k ) {
 87         int nd = find(k);
 88         cnt[nd]--;
 89         update(nd);
 90         splay(nd,0);
 91     }
 92     int gnext( int k ) {
 93         insert( k );
 94         int nd = find( k );
 95         cnt[nd]--;
 96         update(nd);
 97         splay(nd,0);
 98         int rnd = son[nd][1];
 99         if( !rnd ) fprintf( stderr, "gnext k=%d\n", k );
100         int rt = key[rnd];
101         while( son[rnd][0] ) {
102             rnd = son[rnd][0];
103             rt = min( rt, key[rnd] );
104         }
105         splay( rnd,0 );
106         return rt;
107     }
108     int gprev( int k ) {
109         insert( k );
110         int nd = find( k );
111         cnt[nd]--;
112         update(nd);
113         splay(nd,0);
114         int lnd = son[nd][0];
115         if( !lnd ) fprintf( stderr, "gprev k=%d\n", k );
116         int rt = key[lnd];
117         while( son[lnd][1] ) {
118             lnd = son[lnd][1];
119             rt = max( rt, key[lnd] );
120         }
121         splay(lnd,0);
122         return rt;
123     }
124     int rank( int k ) {
125         int nd = root;
126         int rt = 0;
127         while(1) {
128             int ls = siz[son[nd][0]];
129             int cs = cnt[nd];
130             if( k==key[nd] ) {
131                 rt += ls+1;
132                 splay( nd,0 );
133                 return rt;
134             }
135             if( k<key[nd] ) {
136                 nd = son[nd][0];
137             } else {
138                 nd = son[nd][1];
139                 rt += ls+cs;
140             }
141         }
142     }
143     int nth( int n ) {
144         int nd = root;
145         while(1) {
146             int ls = siz[son[nd][0]];
147             int cs = cnt[nd];
148             if( n<=ls ) {
149                 nd = son[nd][0];
150             } else if( n<=ls+cs ) {
151                 splay( nd, 0 );
152                 return key[nd];
153             } else {
154                 n -= ls+cs;
155                 nd = son[nd][1];
156             }
157         }
158     }
159     void print( int nd ) {
160         if( !nd ) return;
161         print( son[nd][0] );
162         fprintf( stderr, "%d(%d)  ", key[nd], cnt[nd] );
163         print( son[nd][1] );
164     }
165 };
166 
167 int n;
168 Splay T;
169 int main() {
170     scanf( "%d", &n );
171     while(n--) {
172         int opt, x;
173         scanf( "%d%d", &opt, &x );
174         switch( opt ) {
175             case 1:
176     //            fprintf( stderr, "insert(%d)\n", x );
177                 T.insert(x);
178                 break;
179             case 2:
180     //            fprintf( stderr, "erase(%d)\n", x );
181                 T.erase(x);
182                 break;
183             case 3:
184                 printf( "%d\n", T.rank(x) );
185                 break;
186             case 4:
187                 printf( "%d\n", T.nth(x) );
188                 break;
189             case 5:
190                 printf( "%d\n", T.gprev(x) );
191                 break;
192             case 6:
193                 printf( "%d\n", T.gnext(x) );
194                 break;
195         }
196         //T.print( T.root );
197         //fprintf( stderr, "\n" );
198     }
199 }
View Code

vector:

技术分享
 1 #include <cstdio>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 
 7 vector<int> vc;
 8 void insert( int x ) {
 9     vc.insert( lower_bound(vc.begin(),vc.end(),x), x );
10 }
11 void erase( int x ) {
12     vc.erase( lower_bound(vc.begin(),vc.end(),x) );
13 }
14 int rank( int x ) {
15     return lower_bound(vc.begin(),vc.end(),x)-vc.begin()+1;
16 }
17 int nth( int n ) {
18     return vc[n-1];
19 }
20 int prev( int x ) {
21     return *--lower_bound(vc.begin(),vc.end(),x);
22 }
23 int next( int x ) {
24     return *upper_bound(vc.begin(),vc.end(),x);
25 }
26 
27 int main() {
28     int n;
29     scanf( "%d", &n );
30     while(n--) {
31         int opt, x;
32         scanf( "%d%d", &opt, &x );
33         switch(opt) {
34             case 1:
35                 insert( x );
36                 break;
37             case 2:
38                 erase(x);
39                 break;
40             case 3:
41                 printf( "%d\n", rank(x) );
42                 break;
43             case 4:
44                 printf( "%d\n", nth(x) );
45                 break;
46             case 5:
47                 printf( "%d\n", prev(x) );
48                 break;
49             case 6:
50                 printf( "%d\n", next(x) );
51                 break;
52         }
53     }
54 }
View Code

数据生成器(有一个参数,是随机数种子):

技术分享
 1 #include <cstdio>
 2 #include <set>
 3 #include <cstdlib>
 4 #define R(l,r) ((rand())%((r)-(l)+1)+(l))
 5 using namespace std;
 6 
 7 int all = 1000;   //指令数
 8 int n = 500;      //最开始的插入的数的数量
 9 int maxd = 200;  //最多删除多少个数
10 
11 int a[101100], mn, mx;
12 int d[101100];
13 
14 int main( int argc, char **argv ) {
15     srand(atoi(argv[1]));
16 
17     freopen( "input", "w", stdout );
18     printf( "%d\n", all );
19     int p = all-n;
20     for( int i=1; i<=n; i++ ) 
21         printf( "1 %d\n", a[i]=R(-n,n) );
22     int remain = maxd;
23     for( int i=1; i<=p; i++ ) {
24 AGAIN:
25         if( i%10000==0 ) fprintf( stderr, "%d\n", i );
26         int opt = R(2,6);
27         int x;
28         switch( opt ) {
29             case 2:
30                 if( remain ) {
31                     int ind;
32                     do
33                         ind = R(1,n);
34                     while( !(!d[ind] && a[ind]!=mn && a[ind]!=mx) );
35                     remain--;
36                     d[ind] = 1;
37                     printf( "2 %d\n", a[ind] );
38                 } else goto AGAIN;
39                 break;
40             case 3:
41                 {
42                     int ind;
43                     do 
44                         ind = R(1,n);
45                     while( !(!d[ind]) );
46                     printf( "3 %d\n", a[ind] );
47                 }
48                 break;
49             case 4:
50                 {
51                     set<int> st;
52                     for( int i=1; i<=n; i++ ) 
53                         if( !d[i] ) st.insert(a[i]);
54                     int x = R(1,st.size());
55                     printf( "4 %d\n", x );
56                 }
57                 break;
58             case 5:
59                 if( mx==mn ) goto AGAIN;
60                 {
61                     printf( "5 %d\n", R(mn+1,mx) );
62                 }
63                 break;
64             case 6:
65                 if( mx==mn ) goto AGAIN;
66                 {
67                     printf( "6 %d\n", R(mn,mx-1) );
68                 }
69                 break;
70         }
71     }
72 }
View Code

 

bzoj3224 普通平衡树

标签:

原文地址:http://www.cnblogs.com/idy002/p/4282200.html

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