luogu 3919
主席树
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string> using namespace std; #define LL long long #define gc getchar() inline int read() {int x = 0, f = 1; char c = gc; while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc;}; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x * f;} inline LL read_LL() {LL x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;} #undef gc const int N = 1e6 + 10; int W[N * 30 * 2], Lson[N * 30 * 2], Rson[N * 30 * 2]; int Root[N]; int Hjt; int n, q; void Build_tree(int l, int r, int &rt) { rt = ++ Hjt; if(l == r) { W[rt] = read(); return ; } int mid = (l + r) >> 1; Build_tree(l, mid, Lson[rt]), Build_tree(mid + 1, r, Rson[rt]); } void Fill(int x, int y) { W[x] = W[y], Lson[x] = Lson[y], Rson[x] = Rson[y]; } void Poi_G(int &rt, int l, int r, int x, int val) { Fill(++ Hjt, rt); rt = Hjt; if(l == r) { W[rt] = val; return ; } int mid = (l + r) >> 1; if(x <= mid) Poi_G(Lson[rt], l, mid, x, val); else Poi_G(Rson[rt], mid + 1, r, x, val); } int Ans; void Poi_A(int rt, int l, int r, int x) { if(l == r) { Ans = W[rt]; return ; } int mid = (l + r) >> 1; if(x <= mid) Poi_A(Lson[rt], l, mid, x); else Poi_A(Rson[rt], mid + 1, r, x); } int main() { n = read(), q = read(); Build_tree(1, n, Root[0]); for(int i = 1; i <= q; i ++) { int v = read(), opt = read(), loc = read(), val; if(opt == 1) val = read(); if(opt == 1) { Root[i] = Root[v]; Poi_G(Root[i], 1, n, loc, val); } else { Poi_A(Root[v], 1, n, loc); Root[i] = Root[v]; cout << Ans << "\n"; } } return 0; }