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;
}

 

posted @ 2018-09-04 21:38  xayata  阅读(120)  评论(0编辑  收藏  举报