首页 > 技术文章 > Treap初步

y7070 2015-12-04 12:37 原文

模板题

  bzoj3224: Tyvj 1728 普通平衡树

  1 #include <bits/stdc++.h>
  2 #define rep(i, a, b) for (int i = a; i <= b; i++)
  3 #define REP(i, a, b) for (int i = a; i < b; i++)
  4 #define drep(i, a, b) for (int i = a; i >= b; i--)
  5 #define pb push_back
  6 #define mp make_pair
  7 #define xx first
  8 #define yy second
  9 using namespace std;
 10 typedef long long i64;
 11 typedef pair<int, int> pii;
 12 const int inf = ~0U >> 1;
 13 const i64 INF = ~0ULL >> 1;
 14 //*****************************
 15  
 16 const int maxn = 100005;
 17 struct node {
 18     int l, r, v, w, sz, rnd;
 19     node () { l = r = v = w = sz = rnd = 0; }
 20 } tr[maxn];
 21 int ndtot, root, ans;
 22  
 23 int read() {
 24     int l = 1, s(0); char ch = getchar_unlocked();
 25     while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar_unlocked(); }
 26     while (ch >= '0' && ch <= '9') { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar_unlocked(); }
 27     return l * s;
 28 }
 29  
 30 void update(int &k) { tr[k].sz = tr[tr[k].l].sz + tr[k].w + tr[tr[k].r].sz; }
 31  
 32 void lturn(int &k) {
 33     int t = tr[k].r; tr[k].r = tr[t].l; tr[t].l = k;
 34     tr[t].sz = tr[k].sz; update(k); k = t;
 35 }
 36  
 37 void rturn(int &k) {
 38     int t = tr[k].l; tr[k].l = tr[t].r; tr[t].r = k;
 39     tr[t].sz = tr[k].sz; update(k); k = t;
 40 }
 41  
 42 void insrt(int &k, int x) {
 43     if (k == 0) {
 44         k = ++ndtot;
 45         tr[k].sz = tr[k].w = 1, tr[k].v = x, tr[k].rnd = rand();
 46         return;
 47     }
 48     tr[k].sz++;
 49     if (tr[k].v == x) tr[k].w++;
 50     else if (x > tr[k].v) {
 51         insrt(tr[k].r, x);
 52         if (tr[tr[k].r].rnd < tr[k].rnd) lturn(k);
 53     }
 54     else {
 55         insrt(tr[k].l, x);
 56         if (tr[tr[k].l].rnd < tr[k].rnd) rturn(k);
 57     }
 58 }
 59  
 60 void del(int &k, int x) {
 61     if (k == 0) return;
 62     if (tr[k].v == x) {
 63         if (tr[k].w > 1) {
 64             tr[k].w--; tr[k].sz--; return;
 65         }
 66         if (tr[k].l * tr[k].r == 0) k = tr[k].l + tr[k].r;
 67         else if (tr[tr[k].l].rnd < tr[tr[k].r].rnd) rturn(k), del(k, x);
 68         else lturn(k), del(k, x);
 69     }
 70     else if (x > tr[k].v) tr[k].sz--, del(tr[k].r, x);
 71     else tr[k].sz--, del(tr[k].l, x);
 72 }
 73  
 74 int query_rnk(int k, int x) {
 75     if (k == 0) return 0;
 76     if (tr[k].v == x) return tr[tr[k].l].sz + 1;
 77     else if (x > tr[k].v) return tr[tr[k].l].sz + tr[k].w + query_rnk(tr[k].r, x);
 78     else return query_rnk(tr[k].l, x);
 79 }
 80  
 81 int query_num(int k, int x) {
 82     if (k == 0) return 0;
 83     if (x <= tr[tr[k].l].sz) return query_num(tr[k].l, x);
 84     else if (x > tr[tr[k].l].sz + tr[k].w) return query_num(tr[k].r, x - tr[tr[k].l].sz - tr[k].w);
 85     else return tr[k].v;
 86 }
 87  
 88 void query_pre(int k, int x) {
 89     if (k == 0) return;
 90     if (x > tr[k].v) {
 91         ans = tr[k].v; query_pre(tr[k].r, x);
 92     }
 93     else query_pre(tr[k].l, x);
 94 }
 95  
 96 void query_sub(int k, int x) {
 97     if (k == 0) return;
 98     if (x < tr[k].v) {
 99         ans = tr[k].v; query_sub(tr[k].l, x);
100     }
101     else query_sub(tr[k].r, x);
102 }
103  
104 int main() {
105     int n; n = read();
106     while (n--) {
107         int op, x; op = read(), x = read();
108         switch(op) {
109             case 1: insrt(root, x); break;
110             case 2: del(root, x); break;
111             case 3: printf("%d\n", query_rnk(root, x)); break;
112             case 4: printf("%d\n", query_num(root, x)); break;
113             case 5: ans = 0; query_pre(root, x); printf("%d\n", ans); break;
114             case 6: ans = 0; query_sub(root, x); printf("%d\n", ans); break;
115         }
116     }
117 }
View Code

 

  bzoj1503: 郁闷的出纳员

    按理来说Treap保持平衡后是不能旋转的,然而这个题乱搞A了,把要查询的点旋转到根上然后干掉。。

 1 #include <bits/stdc++.h>
 2 #define rep(i, a, b) for (int i = a; i <= b; i++)
 3 #define REP(i, a, b) for (int i = a; i < b; i++)
 4 #define drep(i, a, b) for (int i = a; i >= b; i--)
 5 #define mp make_pair
 6 #define pb push_back
 7 #define clr(x) memset(x, 0, sizeof(x))
 8 #define xx first
 9 #define yy second
10 using namespace std;
11 typedef long long i64;
12 const int inf = ~0U>>1;
13 const i64 INF = ~0ULL>>1;
14 //****************************
15  
16 const int maxn = 100005;
17  
18 struct node {
19     int l, r, v, rnd, w, sz;
20     node() { l = r = v = rnd = w = sz = 0; }
21 } tr[maxn];
22 int ndtot, root;
23 void update(int k) { tr[k].sz = tr[tr[k].l].sz + tr[k].w + tr[tr[k].r].sz; }
24 void lturn(int &k) {
25     int t = tr[k].r; tr[k].r = tr[t].l; tr[t].l = k;
26     tr[t].sz = tr[k].sz; update(k); k = t;
27 }
28 void rturn(int &k) {
29     int t = tr[k].l; tr[k].l = tr[t].r; tr[t].r = k;
30     tr[t].sz = tr[k].sz; update(k); k = t;
31 }
32  
33 void insrt(int &k, int x) {
34     if (!k) {
35         k = ++ndtot;
36         tr[k].v = x, tr[k].rnd = rand(), tr[k].w = tr[k].sz = 1;
37         return;
38     }
39     tr[k].sz++;
40     if (tr[k].v == x) tr[k].w++;
41     else if (x > tr[k].v) {
42         insrt(tr[k].r, x);
43         if (tr[tr[k].r].rnd < tr[k].rnd) lturn(k);
44     }
45     else if (x < tr[k].v) {
46         insrt(tr[k].l, x);
47         if (tr[tr[k].l].rnd < tr[k].rnd) rturn(k);
48     }
49 }
50  
51 int query_num(int &k, int x) {
52     if (!k) return 0;
53     if (x <= tr[tr[k].l].sz) return query_num(tr[k].l, x);
54     else if (x > tr[tr[k].l].sz + tr[k].w) return query_num(tr[k].r, x - tr[tr[k].l].sz - tr[k].w);
55     else return tr[k].v;
56 }
57  
58 void fix(int &k, int x) {
59     if (!k) return;
60     if (tr[k].v >= x) {
61         fix(tr[k].l, x);
62         if (tr[k].l && tr[tr[k].l].v >= x) rturn(k);
63     }
64     else {
65         fix(tr[k].r, x);
66         if (tr[k].r && tr[tr[k].r].v >= x) lturn(k);
67     }
68 }
69  
70 char str[5];
71 int main() {
72     int n, m;
73     scanf("%d%d", &n, &m);
74     int tot(0);
75     int be(0);
76     insrt(root, 0x3f3f3f3f);
77     while (n--) {
78         int x;
79         scanf("%s%d", str, &x);
80         if (str[0] == 'I') { if (x >= m) insrt(root, x - tot), be++; }
81         else if (str[0] == 'A') tot += x;
82         else if (str[0] == 'S') {
83             tot -= x;
84             fix(root, m - tot);
85             tr[root].sz -= tr[tr[root].l].sz;
86             tr[tr[root].l] = node();
87             tr[root].l = 0;
88         }
89         else {
90             if (x + 1 > tr[root].sz) puts("-1");
91             else printf("%d\n", query_num(root, tr[root].sz - x) + tot);
92         }
93     }
94     printf("%d\n", be - tr[root].sz + 1);
95     return 0;
96 }
View Code

 

推荐阅读