HDU - 5390 tree line tree cover dictionary tree (see explanations)

HDU - 5390

See the first impression is split tree chain + trie tree line sets, less complexity feel right.

In fact, this path is very special, it is a point change affects only son to the root of the path, and seek the optimal value of this problem can be superimposed.

Therefore, we modify the time marking of the corresponding dfs order, ask when the segment tree down to pray for optimal value for each corresponding interval from.

This will also be the card MLE. . Stratified need to optimize it.

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}

//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int= LOG 30 ; 

int n, m, v [N], tmp [N]?
int QUS [N] [ 3 ]?
int ans [N]?
int Trietot;
int ch [N * 40 ] [ 2 ], sz [N * 40 ]?
int mx = 0 ;
int newNode () { 
    Trietot ++ ; 
    assert (Trietot <N * 40 )? 
    chkmax (mx, Trietot); 
    ch [Trietot] [ 0 ] = 0 ? 
    ch [Trietot] [ 1 ] = 0  ;
    sz [Trietot]= 0;
    return Trietot;
}

struct Trie {
    int Rt;
    void init() {
        Rt = newNode();
    }
    void ins(int x) {
        int u = Rt;
        for(int i = LOG - 1; i >= 0; i--) {
            sz[u]++;
            if(!ch[u][x >> i & 1]) {
                ch[u][x >> i & 1] = newNode();
            }
            u = ch[u][x >> i & 1];
        }
        sz[u]++;
    }
    void del(int x) {
        int u = Rt;
        for(int i = LOG - 1; i >= 0; i--) {
            sz[u]--;
            u = ch[u][x >> i & 1];
        }
        sz[u]--;
    }
    int query(int x) {
        int u = Rt, ret = 0;
        if(!sz[u]) return 0;
        for(int i = LOG - 1; i >= 0; i--) {
            if(sz[ch[u][(x >> i & 1) ^ 1]]) {
                ret += 1 << i;
                u = ch[u][(x >> i & 1) ^ 1];
            }
            else {
                u = ch[u][x >> i & 1];
            }
        }
        return ret;
    }
} T[N << 2];


#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
void build(int tar, int cur, int l, int r, int rt) {
    if(cur == tar) {
        T[rt].init();
        return;
    }
    if(l == r) return;
    int mid = l + r >> 1;
    build(tar, cur + 1, lson);
    build(tar, cur + 1, rson);
}
void update(int tar, int cur, int L, int R, int val, int l, int r, int rt) {
    if(L > R) return;
    if(L <= l && r <= R) {
        if(cur == tar) {
            if(val > 0) T[rt].ins(val);
            else T[rt].del(-val);
        }
        return;
    }
    if(l == r) return;
    int mid = l + r >> 1;
    if(L <= mid) update(tar, cur + 1, L, R, val, lson);
    if(R > mid) update(tar, cur + 1, L, R, val, rson);
}

int query(int tar, int cur, int p, int val, int l, int r, int rt) {
    if(cur == tar) {
        return T[rt].query(val);
    }
    if(l == r) return 0;
    int mid = l + r >> 1;
    if(p <= mid) return query(tar, cur + 1, p, val, lson);
    else return query(tar, cur + 1, p, val, rson);
}

void initTrie(int depth) {
    Trietot = 0;
    build(depth, 0, 1, n, 1);
}

vector<int> G[N];
int in[N], ot[N], idx;

void dfs(int u) {
    in[u] = ++idx;
    for(auto &v : G[u]) {
        dfs(v);
    }
    ot[u] = idx;
}

void init() {
    idx = 0;
    for(int i = 1; i <= n; i++) {
        G[i].clear();
    }
}

int main() {
    int T; scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &n, &m);
        init();
        for(int i = 2; i <= n; i++) {
            int par; scanf("%d", &par);
            G[par].push_back(i);
        }
        for(int i = 1; i <= n; i++) {
            scanf("%d", &v[i]);
            tmp[i] = v[i];
        }
        for(int i = 1; i <= m; i++) {
            scanf("%d%d", &qus[i][0], &qus[i][1]);
            if(qus[i][0] == 0) scanf("%d", &qus[i][2]);
            ans[i] = 0;
        }
        dfs(1);
        for(int depth = 0; depth <= 17; depth++) {
            initTrie(depth);

            for(int i = 1; i <= n; i++) {
                v[i] = tmp[i];
                update(depth, 0, in[i], ot[i], v[i], 1, n, 1);
            }
            for(int i = 1; i <= m; i++) {
                if(!qus[i][0]) {
                    update(depth, 0, in[qus[i][1]], ot[qus[i][1]], -v[qus[i][1]], 1, n, 1);
                    v[qus[i][1]] = qus[i][2];
                    update(depth, 0, in[qus[i][1]], ot[qus[i][1]], v[qus[i][1]], 1, n, 1);
                }
                else {
                    chkmax(ans[i], query(depth, 0, in[qus[i][1]], v[qus[i][1]], 1, n, 1));
                }
            }
        }

        for(int i = 1; i <= m; i++) {
            if(qus[i][0]) {
                printf("%d\n", ans[i]);
            }
        }
    }
    return 0;
}

/*
*/

 

Guess you like

Origin www.cnblogs.com/CJLHY/p/11183306.html