• HDU


    HDU - 5390

    看到的第一感觉就是树链剖分 + 线段树套字典树, 感觉复杂度不太对。

    其实这种路径其实很特殊, 一个点改变只会影响它儿子到根的路径, 并且这种求最优值问题可以叠加。

    所以我们修改的时候对对应dfs序打标记, 询问的时候在线段树上从上往下对每个对应区间求个最优值。

    这样还会被卡MLE。。 需要分层优化一下。

    #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
    ", ans[i]);
                }
            }
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    CISCO一些基本配置
    每日学习
    每日学习(个人作业2)
    每日学习
    团队冲刺第十四天
    每日学习
    团队冲刺第十三天
    每日学习
    团队冲刺第十二天
    2021.5.26
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11183306.html
Copyright © 2020-2023  润新知