【模板】可持久化线段树
如题,这是一个模板。。。
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 #define ls t[u].l 22 #define rs t[u].r 23 24 const int MAXN = 1010100; 25 26 struct SGT 27 { 28 int l, r, w; 29 }t[MAXN << 4]; 30 31 int n, m, opt, old, loc, x, id = 0; 32 int val[MAXN], root[MAXN]; 33 34 inline void Pushup(int u) { t[u].w = t[ls].w + t[rs].w; } 35 36 void Build(int u, int l, int r) 37 { 38 if (l == r) 39 { 40 t[u].w = val[l]; 41 ls = rs = -1; 42 return; 43 } 44 ls = ++id, rs = ++id; 45 int mid = (l + r) >> 1; 46 Build(ls, l, mid); 47 Build(rs, mid + 1, r); 48 Pushup(u); 49 } 50 51 int Add(int pre, int l, int r, int p, int c, int befor) 52 { 53 int cur = ++id; 54 if (l == r) 55 { 56 t[cur].w = c; 57 return cur; 58 } 59 int mid = (l + r) >> 1; 60 t[cur].l = t[pre].l; 61 t[cur].r = t[pre].r; 62 //t[cur].w = t[pre].w - befor + c; 63 if (l < r) 64 if (p <= mid) t[cur].l = Add(t[pre].l, l, mid, p, c, befor); 65 else t[cur].r = Add(t[pre].r, mid + 1, r, p, c, befor); 66 return cur; 67 } 68 69 int Query(int u, int l, int r, int q) 70 { 71 if (l == r) return t[u].w; 72 int mid = (l + r) >> 1; 73 if (q <= mid) return Query(t[u].l, l, mid, q); 74 if (q > mid) return Query(t[u].r, mid + 1, r, q); 75 } 76 77 signed main() 78 { 79 read(n), read(m); 80 for (int i = 1; i <= n; ++i) read(val[i]); 81 Build(root[0] = ++id, 1, n); 82 for (int i = 1; i <= m; ++i) 83 { 84 read(old), read(opt), read(loc); 85 if (opt == 1) 86 read(x), root[i] = Add(root[old], 1, n, loc, x, Query(root[old], 1, n, loc)); 87 if (opt == 2) 88 root[i] = root[i - 1], printf("%d\n", Query(root[old], 1, n, loc)); 89 } 90 return 0; 91 }