SPOJ_QTREE系列题解

Posted cwolf9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 '\n'
#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('\n');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('\n');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 << '\n'; 
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.\n");
            else if(cnt == 1) printf("0\n");
            else printf("%d\n", 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;

以上是关于SPOJ_QTREE系列题解的主要内容,如果未能解决你的问题,请参考以下文章

算法 ---- 子序列系列问题题解(子序列编辑距离回文系列问题)

算法 ---- 子序列系列问题题解(子序列编辑距离回文系列问题)

hbx的毒瘤贪心系列题解

盒子与小球系列题解

盒子与小球系列题解

Leecode大厂热题100道系列题解