zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    C#方法重载 -0024
    C#表达式体方法 (expression-bodied method )
    C# 匿名类型 -0022
    C# 不可变类型 -0021
    C# 属性 -0020
    C# readonly和const -0019
    C# 类的静态成员和实例成员 -0018
    C#中类和结构体的区别 -0017
    C#预处理器指令 -0016
    微信小程序TabBar定义和配置
  • 原文地址:https://www.cnblogs.com/Cwolf9/p/11333502.html
Copyright © 2011-2022 走看看