• SPOJ_QTREE系列题解


    QTREE4

    #pragma comment(linker, "/STACK:102400000,102400000")
    //#include<bits/stdc++.h>
    #include <ctime>
    #include <iostream>
    #include <assert.h>
    #include <vector>
    #include <queue>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define fi first
    #define se second
    #define endl '
    '
    #define o2(x) (x)*(x)
    #define BASE_MAX 31
    #define mk make_pair
    #define eb push_back
    #define SZ(x) ((int)(x).size())
    #define all(x) (x).begin(), (x).end()
    #define clr(a, b) memset((a),(b),sizeof((a)))
    #define iis std::ios::sync_with_stdio(false); cin.tie(0)
    #define my_unique(x) sort(all(x)),x.erase(unique(all(x)),x.end())
    using namespace std;
    #pragma optimize("-O3")
    typedef long long LL;
    typedef unsigned long long uLL;
    typedef pair<int, int> pii;
    inline LL read() {
        LL x = 0;int f = 0;
        char ch = getchar();
        while (ch < '0' || ch > '9') f |= (ch == '-'), ch = getchar();
        while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
        return x = f ? -x : x;
    }
    inline void write(LL x, bool f) {
        if (x == 0) {putchar('0'); if(f)putchar('
    ');else putchar(' ');return;}
        if (x < 0) {putchar('-');x = -x;}
        static char s[23];
        int l = 0;
        while (x != 0)s[l++] = x % 10 + 48, x /= 10;
        while (l)putchar(s[--l]);
        if(f)putchar('
    ');else putchar(' ');
    }
    int lowbit(int x) { return x & (-x); }
    template<class T>T big(const T &a1, const T &a2) { return a1 > a2 ? a1 : a2; }
    template<class T>T sml(const T &a1, const T &a2) { return a1 < a2 ? a1 : a2; }
    template<typename T, typename ...R>T big(const T &f, const R &...r) { return big(f, big(r...)); }
    template<typename T, typename ...R>T sml(const T &f, const R &...r) { return sml(f, sml(r...)); }
    void debug_out() { cerr << '
    '; }
    template<typename T, typename ...R>void debug_out(const T &f, const R &...r) {cerr << f << " ";debug_out(r...);}
    #define debug(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_out(__VA_ARGS__);
    
    const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
    const int HMOD[] = {1000000009, 1004535809};
    const LL BASE[] = {1572872831, 1971536491};
    const int mod = 1e9 + 7;//998244353
    const int MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int MXN = 2e5 + 7;
    const int MXE = 4e5 + 7;
    int n, m;
    struct lp {
        int v, nex;
        int w;
    } cw[MXE];
    int tot, head[MXN];
    
    namespace LCA {
        int dis[MXN], up[MXN][20], lens[MXN];
        void dfs(int u, int ba, int d) {
            up[u][0] = ba; lens[u] = d;
            for(int i = 1; i < 20; ++i) up[u][i] = up[up[u][i-1]][i-1];
            for(int i = head[u], v; ~i; i = cw[i].nex) {
                v = cw[i].v;
                if(v == ba) continue;
                dis[v] = dis[u] + cw[i].w;
                dfs(v, u, d + 1);
            }
        }
        int lca(int x, int y) {
            if(lens[x] < lens[y]) swap(x, y);
            for(int i = 19; i >= 0; --i) {
                if(lens[up[x][i]] >= lens[y]) {
                    x = up[x][i];
                }
            }
            if(x == y) return x;
            for(int i = 19; i >= 0; --i) {
                if(up[x][i] != up[y][i]) {
                    x = up[x][i], y = up[y][i];
                }
            }
            return up[x][0];
        }
        int query(int i, int j) {
            return dis[i] + dis[j] - 2 * dis[lca(i, j)];
        }
    }
    
    //namespace LCA {
    //    int dis[MXN], up[MXN][20], lg[MXN], DEP[MXN];
    //    void dfs(int u, int ba) {
    //        DEP[u] = DEP[ba] + 1;
    //        for(int i = head[u], v; ~i; i = cw[i].nex) {
    //            v = cw[i].v;
    //            if(v == ba) continue;
    //            dis[v] = dis[u] + cw[i].w, up[v][0] = u;
    //            dfs(v, u);
    //        }
    //    }
    //    void init() {
    //        for (int i = 2; i <= n; ++i) lg[i] = lg[i / 2] + 1;;
    //        dis[1] = 0;
    //        dfs(1, -1);
    //        for (int j = 1; j <= lg[n]; ++j)
    //            for (int i = 1; i <= n; ++i) up[i][j] = up[up[i][j - 1]][j - 1];
    //    }
    //    int lca(int x, int y) {
    //        if (DEP[x] > DEP[y]) swap(x, y);
    //        int k = DEP[y] - DEP[x];
    //        for (int i = 0; k; k = k / 2, ++i)
    //            if (k & 1) y = up[y][i];
    //        if (x == y) return x;
    //        k = DEP[x];
    //        for (int i = lg[k]; i >= 0; --i)
    //            if (up[x][i] != up[y][i]) x = up[x][i], y = up[y][i];
    //        return up[x][0];
    //    }
    //    int query(int i, int j) {
    //        return dis[i] + dis[j] - 2 * dis[lca(i, j)];
    //    }
    //}
    
    //namespace LCA {
    //    int dis[MXN], up[MXN][20], lens[MXN];
    //    int cnt, dfn[MXN], en[MXN], LOG[MXN];
    //    void dfs(int u, int ba) {
    //        lens[u] = lens[ba] + 1;
    //        dfn[++cnt] = u;
    //        en[u] = cnt;
    //        for(int i = head[u], v; ~i; i = cw[i].nex) {
    //            v = cw[i].v;
    //            if(v == ba) continue;
    //            dis[v] = dis[u] + cw[i].w;
    //            dfs(v, u);
    //            dfn[++ cnt] = u;
    //        }
    //    }
    //    inline int cmp(int u, int v) {
    //        return lens[u] < lens[v] ? u: v;
    //    }
    //    void init() {
    //        cnt = 0;
    //        dis[0] = lens[0] = 0;
    //        dfs(1, 0);
    //        LOG[1] = 0;
    //        for(int i = 2; i <= cnt; ++i) LOG[i] = LOG[i-1] + ((1<<(LOG[i-1]+1))==i);
    //        for(int i = 1; i <= cnt; ++i) up[i][0] = dfn[i];
    //        for(int j = 1; (1<<j) <= cnt; ++j)
    //            for(int i = 1; i + (1<<j) -1 <= cnt; ++i)
    //                up[i][j] = cmp(up[i][j-1], up[i+(1<<(j-1))][j-1]);
    //    }
    //    inline int lca(int x, int y) {
    //        int l = en[x], r = en[y];
    //        if(l > r) swap(l, r);
    //        int k = LOG[r - l + 1];
    //        return cmp(up[l][k], up[r-(1<<k)+1][k]);
    //    }
    //    inline int query(int i, int j) {
    //        return dis[i] + dis[j] - 2 * dis[lca(i, j)];
    //    }
    //}
    
    int siz[MXN], hvy, hvysiz, mxsz, vis[MXN];
    int col[MXN], fa[MXN], dis[MXN][20];
    int dep[MXN];
    struct heap {
        priority_queue<int> A, B;  // heap=A-B
        void insert(int x) { A.push(x); }
        void erase(int x) { B.push(x); }
        inline int size() { return A.size() - B.size(); }
        inline int top() {
            if(size() <= 0) return -INF;
            while (!B.empty() && A.top() == B.top()) A.pop(), B.pop();
            return A.top();
        }
        inline void pop() {
            while (!B.empty() && A.top() == B.top()) A.pop(), B.pop();
            A.pop();
        }
        inline int top2() {
            int t = top(), ret;
            pop();
            ret = top();
            A.push(t);
            return ret;
        }
        inline int mx() {
            if(size() < 2) return - INF;
            int t = top(), ret;
            pop();
            ret = top();
            A.push(t);
            return ret + t;
        }
    } disf[MXN], dison[MXN], ans;
    inline void add_edge(int a, int b, int c) {
        cw[++ tot].v = b, cw[tot].nex = head[a], cw[tot].w = c;
        head[a] = tot;
        cw[++ tot].v = a, cw[tot].nex = head[b], cw[tot].w = c;
        head[b] = tot;
    }
    inline int get_dis(int i, int j) {
        if(i == j) return 0;
        if(dis[i][dep[i] - dep[j]]) return dis[i][dep[i] - dep[j]];
        dis[i][dep[i] - dep[j]] = LCA::query(i, j);
        return dis[i][dep[i] - dep[j]];
    }
    void dfs_pre(int u, int ba) {
        siz[u] = 1;
        int mm = 0;
        for(int i = head[u], v; ~i; i = cw[i].nex) {
            v = cw[i].v;
            if(v == ba || vis[v]) continue;
            dfs_pre(v, u);
            siz[u] += siz[v];
            mm = max(mm, siz[v]);
        }
        mm = max(mm, mxsz - siz[u]);
        if(hvy == -1 || mm < hvysiz) {
            hvy = u;
            hvysiz = mm;
        }
    }
    void dfs_siz(int u, int ba) {
        siz[u] = 1;
        for(int i = head[u], v; ~i; i = cw[i].nex) {
            v = cw[i].v;
            if(v == ba || vis[v]) continue;
            dfs_siz(v, u);
            siz[u] += siz[v];
        }
    }
    void dfs_dis(int u, int ba, int d, int rt) {
        disf[rt].insert(d);
        for(int i = head[u], v; ~i; i = cw[i].nex) {
            v = cw[i].v;
            if(v == ba || vis[v]) continue;
            dfs_dis(v, u, d + cw[i].w, rt);
        }
    }
    void dfs_get(int lstrt) {
    //    debug(u, _n, hvy)
    //    int lstrt = u;
        vis[lstrt] = 1;
        assert(lstrt == hvy);
        dfs_siz(lstrt, -1);
        dison[lstrt].insert(0);//response itself
        for(int i = head[lstrt], v; ~i; i = cw[i].nex) {
            v = cw[i].v;
            if(vis[v]) continue;
            hvy = -1;
            hvysiz = mxsz = siz[v];
            dfs_pre(v, lstrt);
            dfs_dis(v, lstrt, cw[i].w, hvy);
            fa[hvy] = lstrt;
            dep[hvy] = dep[lstrt] + 1;
            int tmp = disf[hvy].top();
            if(tmp != - INF) dison[lstrt].insert(tmp);
            dfs_get(hvy);
        }
        int tmp = dison[lstrt].mx();
        if(tmp != - INF) ans.insert(tmp);
    }
    void change(int x, int open) {
        int preV = dison[x].mx(), nowV;
        if(open) dison[x].erase(0);
        else dison[x].insert(0);
        nowV = dison[x].mx();
        if(preV != nowV) {
            if(preV != -INF) ans.erase(preV);
            if(nowV != -INF) ans.insert(nowV);
        }
        for(int u = x, ba; fa[u]; u = fa[u]) {
            ba = fa[u];
    //        debug(x, i, fa[i])
            int tmp = disf[u].top();
            preV = dison[ba].mx();
            if(open) disf[u].erase(get_dis(x, ba));
            else disf[u].insert(get_dis(x, ba));
            nowV = disf[u].top();
            if(tmp != nowV) {
                if(tmp != -INF) dison[ba].erase(tmp);
                if(nowV != - INF) dison[ba].insert(nowV);
            }
            nowV = dison[ba].mx();
            if(preV != nowV) {
                if(preV != -INF) ans.erase(preV);
                if(nowV != -INF) ans.insert(nowV);
            }
        }
    }
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("/home/cwolf9/CLionProjects/ccc/in.txt", "r", stdin);
        //freopen("/home/cwolf9/CLionProjects/ccc/out.txt", "w", stdout);
    #endif
        n = read();
        for(int i = 1; i <= n; ++i) head[i] = -1, col[i] = 0;
        tot = -1;
        for(int i = 1, a, b, c; i < n; ++i) {
            a = read(), b = read(), c = read();
            add_edge(a, b, c);
        }
    //    LCA::init();
        LCA::dfs(1, 0, 0);
        hvy = -1;
        hvysiz = mxsz = n;
        dfs_pre(1, -1);
        dfs_get(hvy);
        m = read();
    //    debug(m, get_dis(1, 3), dep[1], dep[3])
        char op[3];
        int x, cnt = n;
        while(m --) {
            scanf("%s", op);
            if(op[0] == 'A') {
                if(cnt == 0) printf("They have disappeared.
    ");
                else if(cnt == 1) printf("0
    ");
                else printf("%d
    ", max(ans.top(), 0));
            }else {
                x = read();
                if(col[x] == 0) {
                    change(x, 1);
                    -- cnt;
                }else {
                    change(x, 0);
                    ++ cnt;
                }
                col[x] = !col[x];
            }
        }
    #ifndef ONLINE_JUDGE
        cout << "time cost:" << 1.0*clock()/CLOCKS_PER_SEC << "ms" << endl;
    #endif
        return 0;
    }
    
    
  • 相关阅读:
    HDU4366 Successor 线段树+预处理
    POJ2823 Sliding Window 单调队列
    HDU寻找最大值 递推求连续区间
    UVA846 Steps 二分查找
    HDU3415 Max Sum of MaxKsubsequence 单调队列
    HDU时间挑战 树状数组
    UVA10168 Summation of Four Primes 哥德巴赫猜想
    UESTC我要长高 DP优化
    HDUChess 递推
    HDU4362 Dragon Ball DP+优化
  • 原文地址:https://www.cnblogs.com/Cwolf9/p/11333502.html
Copyright © 2020-2023  润新知