算法模板の数据结构

一、平衡树

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

 

你可能感兴趣的:(数据结构)