算法模板の数据结构

一、平衡树

1、treap树

 1 int key[MAXN], weight[MAXN], child[MAXN][2], size[MAXN];
 2 int stk[MAXN], top, poi_cnt;//not use point
 3 
 4 inline int newNode(int k) {
 5     int x = (top ? stk[top--] : ++poi_cnt);
 6     key[x] = k;
 7     size[x] = 1;
 8     weight[x] = rand();
 9     child[x][0] = child[x][1] = 0;
10     return x;
11 }
12 
13 inline void update(int &x) {
14     size[x] = size[child[x][0]] + size[child[x][1]] + 1;//size[0]=0
15 }
16 
17 inline void rotate(int &x, int t) {
18     int y = child[x][t];
19     child[x][t] = child[y][t ^ 1];
20     child[y][t ^ 1] = x;
21     update(x); update(y);
22     x = y;
23 }
24 
25 void insert(int &x, int k) {
26     if (x == 0) x = newNode(k);
27     else {
28         int t = (key[x] < k);
29         insert(child[x][t], k);
30         if (weight[child[x][t]] < weight[x]) rotate(x, t);
31     }
32     update(x);
33 }
34 
35 void remove(int &x, int k) {
36     if(key[x] == k) {
37         if(child[x][0] && child[x][1]) {
38             int t = weight[child[x][0]] < weight[child[x][1]];
39             rotate(x, t); remove(child[x][t ^ 1], k);
40         }
41         else {
42             stk[++top] = x;
43             x = child[x][0] + child[x][1];
44         }
45     }
46     else remove(child[x][key[x] < k], k);
47     if(x > 0) update(x);
48 }
49 
50 int kth(int &x, int k) {
51     if(x == 0 || k <= 0 || k > size[x]) return 0;
52     int s = 0;
53     if(child[x][1]) s = size[child[x][1]];
54     if(k == s + 1) return key[x];
55     if(k <= s) return kth(child[x][1], k);
56     return kth(child[x][0], k - s - 1);
57 }
View Code

2、伸展树

 1 struct SplayTree {//左右各有一个空结点
 2     struct Node {
 3         int size, lhash, rhash;
 4         char c;
 5         Node *fa, *ch[2];
 6     };
 7     Node statePool[MAXN], *nil, *root;
 8     int stk[MAXN], top;
 9     int ncnt;
10 
11     void init() {
12         nil = statePool;
13         ncnt = 1;
14         top = 0;
15     }
16 
17     Node* new_node(char v, Node* f) {
18         Node* t;
19         if(top) t = &statePool[stk[--top]];
20         else t = &statePool[ncnt++];
21         t->size = 1;
22         t->lhash = t->rhash = t->c = v;
23         t->ch[0] = t->ch[1] = nil;
24         t->fa = f;
25         return t;
26     }
27 
28     void del_node(Node* &x) {
29         stk[top++] = x - statePool;
30         x = nil;
31     }
32 
33     void rotate(Node* x) {
34         Node* y = x->fa;
35         int t = (y->ch[1] == x);
36         y->fa->ch[y->fa->ch[1] == y] = x; x->fa = y->fa;
37         y->ch[t] = x->ch[t ^ 1]; x->ch[t ^ 1]->fa = y;
38         x->ch[t ^ 1] = y; y->fa = x;
39         update(y);
40     }
41 
42     void splay(Node* x, Node* f) {
43         while(x->fa != f) {
44             if(x->fa->fa == f) rotate(x);
45             else {
46                 Node *y = x->fa, *z = y->fa;
47                 if((z->ch[1] == y) == (y->ch[1] == x)) rotate(y);
48                 else rotate(x);
49                 rotate(x);
50             }
51         }
52         update(x);
53         if(x->fa == nil) root = x;
54     }
55 
56     Node* kth(int k) {
57         Node* x = root;
58         while(true) {
59             int t = x->ch[0]->size + 1;
60             if(t == k) break;
61             if(t > k) x = x->ch[0];
62             else x = x->ch[1], k -= t;
63         }
64         return x;
65     }
66 
67     void insert(int pos, char c) {
68         splay(kth(pos), nil);
69         splay(kth(pos + 1), root);
70         root->ch[1]->ch[0] = new_node(c, root->ch[1]);
71         update(root->ch[1]); update(root);
72     }
73 
74     void modify(int pos, char c) {
75         splay(kth(pos), nil);
76         root->c = c;
77         update(root);
78     }
79 
80     void remove(int pos) {
81         splay(kth(pos - 1), nil);
82         splay(kth(pos + 1), root);
83         del_node(root->ch[1]->ch[0]);
84         update(root->ch[1]); update(root);
85     }
86 } splay;
View Code

二、其他

1、左偏树(HDU 1512)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int MAXN = 100010;
 7 
 8 int n, m;
 9 int fa[MAXN];
10 
11 int key[MAXN], child[MAXN][2], dist[MAXN];
12 int stk[MAXN], top, node_cnt;
13 int root[MAXN];
14 
15 void init() {
16     dist[0] = -1;
17     top = node_cnt = 0;
18 }
19 
20 int newNode(int k) {
21     int x = top ? stk[top--] : ++node_cnt;
22     dist[x] = 1; key[x] = k;
23     child[x][0] = child[x][1] = 0;
24     return x;
25 }
26 
27 void maintain(int &x) {
28     if(dist[child[x][0]] < dist[child[x][1]])
29         swap(child[x][0], child[x][1]);
30     dist[x] = dist[child[x][0]] + 1;
31 }
32 
33 int merge(int &x, int &y) {
34     if(x == 0) return y;
35     if(y == 0) return x;
36     if(key[y] > key[x]) swap(x, y);
37     child[x][1] = merge(child[x][1], y);
38     maintain(x);
39     return x;
40 }
41 
42 int del(int &x) {
43     if(x != 0) {
44         stk[++top] = x;
45         return merge(child[x][0], child[x][1]);
46     }
47     return 0;
48 }
49 
50 int getfather(int x) {
51     return fa[x] == x ? x : fa[x] = getfather(fa[x]);
52 }
53 
54 int merge2(int x, int y) {
55     return fa[x] = y;
56 }
57 
58 void solve(int u, int v) {
59     int fu = getfather(u);
60     int fv = getfather(v);
61     if(fu == fv) {
62         printf("-1\n");
63         return ;
64     }
65     int p1 = newNode(key[root[fu]] / 2);
66     int p2 = newNode(key[root[fv]] / 2);
67     int p3 = del(root[fu]);
68     int p4 = del(root[fv]);
69     p3 = merge(p1, p3);
70     p4 = merge(p2, p4);
71     int x = merge2(fu, fv);
72     root[x] = merge(p3, p4);
73     printf("%d\n", key[root[x]]);
74 }
75 
76 int main() {
77     int k, u, v;
78     while(scanf("%d", &n) != EOF) {
79         init();
80         for(int i = 1; i <= n; ++i) {
81             scanf("%d", &k);
82             root[i] = newNode(k);
83             fa[i] = i;
84         }
85         scanf("%d", &m);
86         while(m--) {
87             scanf("%d%d", &u, &v);
88             solve(u, v);
89         }
90     }
91 }
View Code

2、RMQ+LCA(在线)

 1 int RMQ[2*MAXN], mm[2*MAXN], best[20][2*MAXN];
 2 
 3 void initMM() {
 4     mm[0] = -1;
 5     for(int i = 1; i <= MAXN * 2 - 1; ++i)
 6        mm[i] = ((i&(i-1)) == 0) ? mm[i-1] + 1 : mm[i-1];
 7 }
 8 
 9 void initRMQ(int n) {
10     int i, j, a, b;
11     for(i = 1; i <= n; ++i) best[0][i] = i;
12     for(i = 1; i <= mm[n]; ++i) {
13         for(j = 1; j <= n + 1 - (1 << i); ++j) {
14           a = best[i - 1][j];
15           b = best[i - 1][j + (1 << (i - 1))];
16           if(RMQ[a] < RMQ[b]) best[i][j] = a;
17           else best[i][j] = b;
18         }
19     }
20 }
21 
22 int askRMQ(int a,int b) {
23     int t;
24     t = mm[b - a + 1]; b -= (1 << t)-1;
25     a = best[t][a]; b = best[t][b];
26     return RMQ[a] < RMQ[b] ? a : b;
27 }
28 
29 int dfs_clock, num[2*MAXN], pos[MAXN];//LCA
30 
31 void dfs_LCA(int f, int u, int dep) {
32     pos[u] = ++dfs_clock;
33     RMQ[dfs_clock] = dep; num[dfs_clock] = u;
34     for(int p = head[u]; p; p = next[p]) {
35         if(to[p] == f) continue;
36         dfs_LCA(u, to[p], dep + 1);
37         ++dfs_clock;
38         RMQ[dfs_clock] = dep; num[dfs_clock] = u;
39     }
40 }
41 
42 int LCA(int u, int v) {
43     if(pos[u] > pos[v]) swap(u, v);
44     return num[askRMQ(pos[u], pos[v])];
45 }
46 
47 void initLCA(int n) {
48     dfs_clock = 0;
49     dfs_LCA(0, root, 0);
50     initRMQ(dfs_clock);
51 }
View Code

3、主席树(POJ 2104)

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int MAXN = 100010;
 6 
 7 struct Node {
 8     int L, R, sum;
 9 };
10 Node T[MAXN * 20];
11 int T_cnt;
12 
13 void insert(int &num, int &x, int L, int R) {
14     T[T_cnt++] = T[x]; x = T_cnt - 1;
15     ++T[x].sum;
16     if(L == R) return ;
17     int mid = (L + R) >> 1;
18     if(num <= mid) insert(num, T[x].L, L, mid);
19     else insert(num, T[x].R, mid + 1, R);
20 }
21 
22 int query(int i, int j, int k, int L, int R) {
23     if(L == R) return L;
24     int t = T[T[j].L].sum - T[T[i].L].sum;
25     int mid = (R + L) >> 1;
26     if(k <= t) return query(T[i].L, T[j].L, k, L, mid);
27     else return query(T[i].R, T[j].R, k - t, mid + 1, R);
28 }
29 
30 struct A {
31     int x, idx;
32     bool operator < (const A &rhs) const {
33         return x < rhs.x;
34     }
35 };
36 
37 A a[MAXN];
38 int rank[MAXN], root[MAXN];
39 int n, m;
40 
41 int main() {
42     T[0].L = T[0].R = T[0].sum = 0;
43     root[0] = 0;
44     while(scanf("%d%d", &n, &m) != EOF) {
45         for(int i = 1; i <= n; ++i) {
46             scanf("%d", &a[i].x);
47             a[i].idx = i;
48         }
49         sort(a + 1, a + n + 1);
50         for(int i = 1; i <= n; ++i) rank[a[i].idx] = i;
51         T_cnt = 1;
52         for(int i = 1; i <= n; ++i) {
53             root[i] = root[i - 1];
54             insert(rank[i], root[i], 1, n);
55         }
56         while(m--) {
57             int i, j, k;
58             scanf("%d%d%d", &i, &j, &k);
59             printf("%d\n", a[query(root[i - 1], root[j], k, 1, n)].x);
60         }
61     }
62 }
View Code

4、树状数组

 1 int lowbit(int x) {
 2     return x & (-x);
 3 }
 4 
 5 int get_sum(int k) {
 6     int ans = 0;
 7     while(k > 0) {
 8         ans += tree[k];
 9         k -= lowbit(k);
10     }
11     return ans;
12 }
13 
14 void modify(int k, int val) {
15     while(k <= n) {
16         tree[k] += val;
17         k += lowbit(k);
18     }
19 }
View Code

5、DLX舞蹈链

①POJ 3076

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <vector>
  6 using namespace std;
  7 
  8 const int MAXC = 1024 + 10;
  9 const int MAXR = 4096 + 10;
 10 const int MAXP = MAXR * 4 + MAXC;
 11 
 12 struct DLX {
 13     int n, sz;//列数,结点总数
 14     int sum[MAXC];//每列拥有的结点数
 15     int row[MAXP], col[MAXP];//结点所在的行和列
 16     int left[MAXP], right[MAXP], up[MAXP], down[MAXP];//十字链表
 17     int ansd, ans[MAXR];
 18 
 19     void init(int nn) {
 20         n = nn;
 21         for(int i = 0; i <= n; ++i) {
 22             up[i] = down[i] = i;
 23             left[i] = i - 1; right[i] = i + 1;
 24         }
 25         right[n] = 0; left[0] = n;
 26         sz = n + 1;
 27         memset(sum, 0, sizeof(sum));
 28     }
 29 
 30     void add_row(int r, vector<int> columns) {
 31         int first = sz;
 32         for(int i = 0, len = columns.size(); i < len; ++i) {
 33             int c = columns[i];
 34             left[sz] = sz - 1; right[sz] = sz + 1; down[sz] = c; up[sz] = up[c];
 35             down[up[c]] = sz; up[c] = sz;
 36             row[sz] = r; col[sz] = c;
 37             ++sum[c]; ++sz;
 38         }
 39         right[sz - 1] = first; left[first] = sz - 1;
 40     }
 41 
 42     void remove(int c) {
 43         left[right[c]] = left[c];
 44         right[left[c]] = right[c];
 45         for(int i = down[c]; i != c; i = down[i])
 46             for(int j = right[i]; j != i; j = right[j]) {
 47                 up[down[j]] = up[j]; down[up[j]] = down[j]; --sum[col[j]];
 48             }
 49     }
 50 
 51     void restore(int c) {
 52         for(int i = up[c]; i != c; i = up[i])
 53             for(int j = left[i]; j != i; j = left[j]) {
 54                 up[down[j]] = j; down[up[j]] = j; ++sum[col[j]];
 55             }
 56         left[right[c]] = c;
 57         right[left[c]] = c;
 58     }
 59 
 60     bool dfs(int d) {
 61         if(right[0] == 0) {
 62             ansd = d;
 63             return true;
 64         }
 65         int c = right[0];
 66         for(int i = right[0]; i != 0; i = right[i]) if(sum[i] < sum[c]) c = i;
 67         remove(c);
 68         for(int i = down[c]; i != c; i = down[i]) {
 69             ans[d] = row[i];
 70             for(int j = right[i]; j != i; j = right[j]) remove(col[j]);
 71             if(dfs(d + 1)) return true;
 72             for(int j = left[i]; j != i; j = left[j]) restore(col[j]);
 73         }
 74         restore(c);
 75         return false;
 76     }
 77 
 78     bool solve(vector<int> &v) {
 79         v.clear();
 80         if(!dfs(0)) return false;
 81         for(int i = 0; i < ansd; ++i) v.push_back(ans[i]);
 82         return true;
 83     }
 84 };
 85 
 86 DLX solver;
 87 
 88 const int SLOT = 0;
 89 const int ROW = 1;
 90 const int COL = 2;
 91 const int SUB = 3;
 92 
 93 inline int encode(int a, int b, int c) {
 94     return a * 256 + b * 16 + c + 1;
 95 }
 96 
 97 void decode(int code, int &a, int &b, int &c) {
 98     --code;
 99     c = code % 16; code /= 16;
100     b = code % 16; code /= 16;
101     a = code;
102 }
103 
104 char puzzle[16][20];
105 
106 bool read() {
107     for(int i = 0; i < 16; ++i)
108         if(scanf("%s", puzzle[i]) == EOF) return false;
109     return true;
110 }
111 
112 int main() {
113     int kase = 0;
114     while(read()) {
115         if(++kase != 1) printf("\n");
116         solver.init(1024);
117         for(int r = 0; r < 16; ++r)
118             for(int c = 0; c < 16; ++c)
119                 for(int v = 0; v < 16; ++v)
120                     if(puzzle[r][c] == '-' || puzzle[r][c] == 'A' + v) {
121                         vector<int> columns;
122                         columns.push_back(encode(SLOT, r, c));
123                         columns.push_back(encode(ROW, r, v));
124                         columns.push_back(encode(COL, c, v));
125                         columns.push_back(encode(SUB, (r/4)*4+c/4, v));
126                         solver.add_row(encode(r, c, v), columns);
127                     }
128         vector<int> ans;
129         solver.solve(ans);
130         for(int i = 0, len = ans.size(); i < len; ++i) {
131             int r, c, v;
132             decode(ans[i], r, c, v);
133             puzzle[r][c] = 'A' + v;
134         }
135         for(int i = 0; i < 16; ++i) printf("%s\n", puzzle[i]);
136     }
137 }
View Code

②HDU 4735

 1 struct DLX {//HDU 4735
 2     int n, sz;//列数,结点总数
 3     int sum[MAXC];//每列拥有的结点数
 4     int row[MAXP], col[MAXP];//结点所在的行和列
 5     int left[MAXP], right[MAXP], up[MAXP], down[MAXP];//十字链表
 6     int ans, anst[MAXR];
 7 
 8     void init(int nn) {
 9         n = nn;
10         for(int i = 0; i <= n; ++i) {
11             up[i] = down[i] = i;
12             left[i] = i - 1; right[i] = i + 1;
13             col[i] = i;
14         }
15         right[n] = 0; left[0] = n;
16         sz = n + 1;
17         memset(sum, 0, sizeof(sum));
18     }
19 
20     void add_row(int r, vector<int> &columns) {
21         int first = sz;
22         for(int i = 0, len = columns.size(); i < len; ++i) {
23             int c = columns[i];
24             left[sz] = sz - 1; right[sz] = sz + 1; down[sz] = c; up[sz] = up[c];
25             down[up[c]] = sz; up[c] = sz;
26             row[sz] = r; col[sz] = c;
27             ++sum[c]; ++sz;
28         }
29         right[sz - 1] = first; left[first] = sz - 1;
30     }
31 
32     void remove(int c) {
33         for(int i = down[c]; i != c; i = down[i]) {
34             left[right[i]] = left[i];
35             right[left[i]] = right[i];
36         }
37     }
38 
39     void restore(int c) {
40         for(int i = down[c]; i != c; i = down[i]) {
41             left[right[i]] = i;
42             right[left[i]] = i;
43         }
44     }
45 
46     bool vis[MAXC];
47 
48     int A() {
49         memset(vis, 0, sizeof(vis));
50         int ret = 0;
51         for(int i = right[0]; i != 0; i = right[i]) if(!vis[i]) {
52             ++ret;
53             for(int j = down[i]; j != i; j = down[j]) {
54                 for(int k = right[j]; k != j; k = right[k]) vis[col[k]] = true;
55             }
56         }
57         return ret;
58     }
59 
60     void dfs(int dep) {
61         if(dep + A() > boys) return ;
62         int tmp = 0;
63         for(int i = 0; i < dep; ++i) tmp += boy[anst[i]];
64         if(dep - tmp >= ans) return ;
65         if(right[0] == 0) {
66             ans = dep - tmp;
67             return ;
68         }
69         int c = right[0];
70         for(int i = right[0]; i != 0; i = right[i]) if(sum[i] < sum[c]) c = i;
71         for(int i = down[c]; i != c; i = down[i]) {
72             anst[dep] = row[i];
73             remove(i);
74             for(int j = right[i]; j != i; j = right[j]) remove(j);
75             dfs(dep + 1);
76             for(int j = left[i]; j != i; j = left[j]) restore(j);
77             restore(i);
78         }
79     }
80 
81     bool solve() {
82         ans = n + 1;
83         dfs(0);
84         return ans != n + 1;
85     }
86 } S;
View Code

6、动态树LCT

 1 struct LCT {
 2     struct Node {
 3         Node *ch[2], *fa;
 4         int val;
 5         bool rt, rev;
 6     } statePool[MAXV], *nil;
 7     int ncnt;
 8 
 9     void init() {
10         nil = statePool;
11         ncnt = 1;
12     }
13 
14     void rotate(Node *x) {
15         Node *y = x->fa;
16         int t = (y->ch[1] == x);
17 
18         if(y->rt) y->rt = false, x->rt = true;
19         else y->fa->ch[y->fa->ch[1] == y] = x;
20         x->fa = y->fa;
21 
22         (y->ch[t] = x->ch[t ^ 1])->fa = y;
23         (x->ch[t ^ 1] = y)->fa = x;
24         update(y);
25     }
26 
27     void update_rev(Node *x) {
28         if(x == nil) return ;
29         x->rev = !x->rev;
30         swap(x->ch[0], x->ch[1]);
31     }
32 
33     void pushdown(Node *x) {
34         if(x->rev) {
35             FOR(k, 2) update_rev(x->ch[k]);
36             x->rev = false;
37         }
38     }
39 
40     void push(Node *x) {
41         if(!x->rt) push(x->fa);
42         pushdown(x);
43     }
44 
45     void splay(Node *x) {
46         push(x);
47         while(!x->rt) {
48             Node *f = x->fa, *ff = f->fa;
49             if(!f->rt) rotate(((ff->ch[1] == f) && (f->ch[1] == x)) ? f : x);
50             rotate(x);
51         }
52         update(x);
53     }
54 
55     Node* access(Node *x) {
56         Node *y = nil;
57         while(x != nil) {
58             splay(x);
59             x->ch[1]->rt = true;
60             (x->ch[1] = y)->rt = false;
61             update(x);
62             y = x; x = x->fa;
63         }
64         return y;
65     }
66 
67     void be_root(Node *x) {
68         access(x);
69         splay(x);
70         update_rev(x);
71     }
72 
73     void link(Node *x, Node *y) {
74         be_root(x);
75         x->fa = y;
76     }
77 
78     void cut(Node *x, Node *y) {
79         be_root(x);
80         access(x);
81         splay(y);
82         y->fa = nil;
83     }
84 
85     void modify_set(Node *x, Node *y, int w) {
86         be_root(x);
87         update_set(access(y), w);
88     }
89 
90     void query(Node *x, Node *y) {
91         be_root(x);
92         Node *r = access(y);
93         if(r->max[1] == NINF) puts("ALL SAME");
94         else printf("%d %d\n", r->max[1], r->cnt[1]);
95     }
96 };
View Code

7、树链剖分

 1 int fa[MAXV], size[MAXV], son[MAXV], top[MAXV], tid[MAXV], dep[MAXV];
 2 int dfs_clock;
 3 
 4 void dfs_size(int u, int f, int depth) {
 5     fa[u] = f; dep[u] = depth;
 6     size[u] = 1; son[u] = 0;
 7     int maxsize = 0;
 8     for(int p = head[u]; ~p; p = next[p]) {
 9         int &v = to[p];
10         if(v == f) continue;
11         dfs_size(v, u, depth + 1);
12         size[u] += size[v];
13         if(size[v] > maxsize) {
14             son[u] = v;
15             maxsize = size[v];
16         }
17     }
18 }
19 
20 void dfs_heavy_edge(int u, int ancestor) {
21     tid[u] = ++dfs_clock; top[u] = ancestor;
22     if(son[u]) dfs_heavy_edge(son[u], ancestor);
23     for(int p = head[u]; ~p; p = next[p]) {
24         int &v = to[p];
25         if(v == fa[u] || v == son[u]) continue;
26         dfs_heavy_edge(v, v);
27     }
28 }
29 
30 void modifyFlip(int a, int b) {
31     while(top[a] != top[b]) {
32         if(dep[top[a]] < dep[top[b]]) swap(a, b);
33         modifyFlip(1, 1, n, tid[top[a]], tid[a]);
34         a = fa[top[a]];
35     }
36     if(a != b) {
37         if(dep[a] < dep[b]) swap(a, b);
38         modifyFlip(1, 1, n, tid[son[b]], tid[a]);
39     }
40 }
View Code

 

posted @ 2013-08-19 23:27  Oyking  阅读(474)  评论(0编辑  收藏  举报