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;
}

原文地址:https://www.cnblogs.com/Cwolf9/p/11333502.html

时间: 2024-11-04 03:16:09

SPOJ_QTREE系列题解的相关文章

hbx的毒瘤贪心系列题解

毒瘤hbx的贪心专题系列题解 A Maximal gcd 题意:现在给定一个正整数 n.你需要找到 k 个严格递增的正整数a1,?a2,?...,?ak,满足他们的和等于 n 并且他们的最大公因数尽量大.如果不可能请输出 -1.\(1\leq n,k \leq 10^{10}\) 题解:把 n 的所有因子找出来后,求最大因子 x 满足\(x* \frac {k* (k+1)}{2}\leq n\)即可.序列就是\(1* x,2* x,...,(k-1)* x,n-x* \frac{k* (k-1

Heoi2014系列题解

Bzoj3609人人尽说江南好 显然我们要聚集起一个大小为m的石堆需要m - 1次的合并操作,我们可以把贡献单独拿出来看,我们将场上所有石子移动到无法移动的状态步数一定和把所有石子依次合并至上限的次数一样,因为...此处省略一千言.. 大概意会一下吧,感觉不好言传...大概是每次合并贡献实际是相同的这种,就像你算$x_1*x_2*x_3*...*x_n$的值一样,你没有办法通过改变乘的顺序减少乘的次数. 所以直接算出需要多少步,判一判奇偶输出答案. 代码 : #include<bits/stdc

[Leetcode] Sum 系列

Sum 系列题解 Two Sum题解 题目来源:https://leetcode.com/problems/two-sum/description/ Description Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one sol

BZOJ 4030: [HEOI2015]小L的白日梦

4030: [HEOI2015]小L的白日梦 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 172  Solved: 39[Submit][Status][Discuss] Description 在某一天,你有了一个女性朋友. 你打算利用k天时间陪她,每天有很多种娱乐方式可供选择,你需要从中选择一种进行(一天只能进行一个项目),比如说一起去看电影.一起去主题公园,一起去逛街等等,一共n种项目.当然每个项目重复太多次你都会觉得无聊,因此第i个项目

Zju1290 Word-Search Wonder(http://begin.lydsy.com/JudgeOnline/problem.php?id=2768)

2768: Zju1290 Word-Search Wonder Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 4  Solved: 2[Submit][Status][Web Board] Description The Pyrates Restaurant was starting to fill up as Valentine McKee walked in. She scanned the crowd for her sister, bro

我又来博客园了

之前自己搞的博客服务器不知道这么了 于是我又来博客园写博客了 看看之前写的sb博客 于是全删了 现在这个博客应该会写一些题解什么的 游记的话我还是会放在foreverpiano.cf这个博客上的 由于我太弱了就没有搞css样式 于是现在博客看起来和chenak的博客差不多 那就差不多吧 upd: 由于博主使用emacs 代码可能略微有些缩进奇怪 拖到Dev格式化一下就可以了(博主的代码应该还是可以看懂的吧233) upddddddddddd: 删除了大量无价值博客,保留了一些. 之后零碎学习笔记

弱省胡策系列简要题解

现在不是非常爽,感觉智商掉没了,就整理一下最近弱省胡策的题目吧. 其实题目质量还是很高的. 如果实在看不懂官方题解,说不定这里bb的能给您一些帮助呢? [弱省胡策]Round #0 A 20%数据,O(n4)傻逼dp. 40%数据,O(n3)傻逼dp. 100%数据,令f(x1,y1,x2,y2)表示从(x1,y1)走到(x2,y2)的路径条数.于是所有路径就是f(1,2,n?1,m)×f(2,1,n,m?1).然而两条路径可能在中间的某个点相交,我们找出最早的交点,并在这个交点互换两条路径的后

Myhchael原创题系列 Mychael vs Kid 【题解】

题目链接 Mychael vs Kid 题解 先说说这题的由来及前身 前身 首先有一个很经典的题目: 维护区间加,查询区间\(gcd\) 如果强行用线段树维护的话,区间加之后就没法直接确定当前区间的\(gcd\),不可直接维护 这个时候就用到了\(gcd\)的一个性质: \[(a,b) = (a - b,b)\] 三个的\(gcd\)也是符合的: \[(a,b,c) = (a,b,c - b) = (a,b - a,c - b)\] 同样可以推广出\(n\)个的情况 \[gcd\{a_i\} =

【题解】吉哥系列故事——恨7不成妻

\(Description:\) 给出区间 \([L,R]\) 求出区间中所有满足没有 \(7\) 这个数并且这个数不会被 \(7\) 整除,同时这个数各位上的和不能被 \(7\) 整除.求 \([L,R]\) 的区间中满足这些条件的数的平方和. \(Sample\) \(Input:\) 3 1 9 10 11 17 17 \(Sample\) \(Output:\) 236 221 0 \(Solution:\) 这题老好玩了,坑了我一个早上,发现他要咱们求得是平方和. 好像不可做的样子,看