1. 程式人生 > >【模板】動態主席樹

【模板】動態主席樹

如題,這是一個模板。。。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <cctype>
  6 
  7 inline void read(int & x)
  8 {
  9     x = 0;
 10     int k = 1;
 11     char c = getchar();
 12     while (!isdigit(c))
13 if (c == '-') c = getchar(), k = -1; 14 else c = getchar(); 15 while (isdigit(c)) 16 x = (x << 1) + (x << 3) + (c ^ 48), 17 c = getchar(); 18 x *= k; 19 } 20 21 struct Node 22 { 23 int l, r, k, q; 24 }q[101010]; 25 26
const int MAXN = 1010100 << 6; 27 int n, m, tot = 0, id = 0; 28 int a[MAXN], b[MAXN], ls[MAXN], rs[MAXN], sum[MAXN]; 29 int T[MAXN], S[MAXN], use[MAXN]; 30 31 char opt[11]; 32 33 inline int lowbit(int x) 34 { 35 return x & (-x); 36 } 37 38 inline int Lsh(int x) 39
{ 40 return std::lower_bound(a + 1, a + tot + 1, x) - a; 41 } 42 43 inline void Pushup(int u) 44 { 45 sum[u] = sum[ls[u]] + sum[rs[u]]; 46 } 47 48 int Build(int l, int r) 49 { 50 int rt = ++id; 51 sum[rt] = 0; 52 if (l != r) 53 { 54 int mid = l + r >> 1; 55 ls[rt] = Build(l, mid); 56 rs[rt] = Build(mid + 1, r); 57 } 58 return rt; 59 } 60 61 int Add(int pre, int l, int r, int x, int cm) 62 { 63 int rt = ++id; 64 ls[rt] = ls[pre], 65 rs[rt] = rs[pre], 66 sum[rt] = sum[pre] + cm; 67 if (l < r) 68 { 69 int mid = l + r >> 1; 70 if (x <= mid) 71 ls[rt] = Add(ls[pre], l, mid, x, cm); 72 else 73 rs[rt] = Add(rs[pre], mid + 1, r, x, cm); 74 } 75 return rt; 76 } 77 78 inline void Modify(int u, int pos, int x) 79 { 80 while (u <= n) 81 { 82 S[u] = Add(S[u], 1, tot, pos, x); 83 u += lowbit(u); 84 } 85 } 86 87 inline int Sum(int u) 88 { 89 int ans = 0; 90 while (u > 0) 91 { 92 ans += sum[ls[use[u]]]; 93 u -= lowbit(u); 94 } 95 return ans; 96 } 97 98 int Query(int u, int v, int ur, int vr, int l, int r, int k) 99 { 100 if (l >= r) return l; 101 int mid = l + r >> 1; 102 int df = Sum(v) - Sum(u) + sum[ls[vr]] - sum[ls[ur]]; 103 if (k <= df) 104 { 105 for (int i = u; i; i -= lowbit(i)) 106 use[i] = ls[use[i]]; 107 for (int i = v; i; i -= lowbit(i)) 108 use[i] = ls[use[i]]; 109 return 110 Query(u, v, ls[ur], ls[vr], l, mid, k); 111 } 112 else 113 { 114 for (int i = u; i; i -= lowbit(i)) 115 use[i] = rs[use[i]]; 116 for (int i = v; i; i -= lowbit(i)) 117 use[i] = rs[use[i]]; 118 return 119 Query(u, v, rs[ur], rs[vr], mid + 1, r, k - df); 120 } 121 } 122 123 signed main() 124 { 125 read(n), read(m); 126 for (int i = 1; i <= n; ++i) 127 read(b[i]), a[++tot] = b[i]; 128 for (int i = 1; i <= m; ++i) 129 { 130 scanf("%s", opt); 131 if (opt[0] == 'Q') 132 read(q[i].l), read(q[i].r), read(q[i].k), q[i].q = 1; 133 else 134 read(q[i].l), read(q[i].r), q[i].q = 0, 135 a[++tot] = q[i].r; 136 } 137 std::sort(a + 1, a + tot + 1); 138 int cur = std::unique(a + 1, a + tot + 1) - a - 1; 139 tot = cur; 140 T[0] = Build(1, tot); 141 for (int i = 1; i <= n; ++i) 142 T[i] = Add(T[i - 1], 1, tot, Lsh(b[i]), 1); 143 for (int i = 1; i <= n; ++i) 144 S[i] = T[0]; 145 for (int i = 1; i <= m; ++i) 146 if (q[i].q) 147 { 148 for (int j = q[i].l - 1; j; j -= lowbit(j)) 149 use[j] = S[j]; 150 for (int j = q[i].r; j; j -= lowbit(j)) 151 use[j] = S[j]; 152 printf("%d\n", a[Query(q[i].l - 1, q[i].r, T[q[i].l - 1], T[q[i].r], 1, tot, q[i].k)]); 153 } 154 else 155 { 156 Modify(q[i].l, Lsh(b[q[i].l]), -1); 157 Modify(q[i].l, Lsh(q[i].r), 1); 158 b[q[i].l] = q[i].r; 159 } 160 return 0; 161 }