tjut 5296

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
using namespace std;
template <class T>
inline bool rd(T &ret) {
    char c; int sgn;
    if (c = getchar(), c == EOF) return 0;
    while (c != '-' && (c<'0' || c>'9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}
template <class T>
inline void pt(T x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) pt(x / 10);
    putchar(x % 10 + '0');
}
typedef long long ll;
typedef pair<int, int> pii;
const int N = 100000 + 100;
struct Edge {
    int from, to, dis, nex;
}edge[N << 1];
int head[N], edgenum;
void add(int u, int v, int d) {
    Edge E = { u,v,d, head[u] };
    edge[edgenum] = E;
    head[u] = edgenum++;
}
int dis[N], fa[N][20], dep[N];
void bfs(int root) {
    queue<int> q;
    fa[root][0] = root;dep[root] = 0;dis[root] = 0;
    q.push(root);
    while (!q.empty()) {
        int u = q.front();q.pop();
        for (int i = 1;i<20;i++)fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (int i = head[u]; ~i;i = edge[i].nex) {
            int v = edge[i].to;if (v == fa[u][0])continue;
            dep[v] = dep[u] + 1;dis[v] = dis[u] + edge[i].dis;fa[v][0] = u;
            q.push(v);
        }
    }
}
int Lca(int x, int y) {
    if (dep[x]<dep[y])swap(x, y);
    for (int i = 0;i<20;i++)if ((dep[x] - dep[y])&(1 << i))x = fa[x][i];
    if (x == y)return x;
    for (int i = 19;i >= 0;i--)if (fa[x][i] != fa[y][i])x = fa[x][i], y = fa[y][i];
    return fa[x][0];
}

int n, q;
int c[N];
set<int>s;
inline int Lowbit(int x) { return x&(-x); }
void change(int i, int x)//i点增量为x
{
    while (i <= n)
    {
        c[i] += x;
        i += Lowbit(i);
    }
}
int sum(int x) {//区间求和 [1,x]
    int ans = 0;
    for (int i = x; i >= 1; i -= Lowbit(i))
        ans += c[i];
    return ans;
}
int p[N], fp[N], top;
void dfs(int u, int fa) {
    p[u] = ++top;
    fp[top] = u;
    for (int i(head[u]); ~i; i = edge[i].nex) {
        int v = edge[i].to; if (v == fa)continue;
        dfs(v, u);
    }
}
int Low(int l, int r) {
    int ans = -1;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (sum(mid) - sum(l-1))r = mid - 1, ans = mid;
        else l = mid + 1;
    }
    return ans;
}
int Up(int l, int r) {
    int ans = -1;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (sum(r) - sum(mid-1))l = mid + 1, ans = mid;
        else r = mid - 1;
    }
    return ans;
}
int main() {
    int T, Cas = 1; rd(T);
    while (T--) {
        memset(c, 0, sizeof c);
        memset(head, -1, sizeof head); edgenum = 0;
        rd(n); rd(q);
        for (int i = 1, u, v, w; i < n; i++) {
            rd(u); rd(v); rd(w);
            add(u, v, w); add(v, u, w);
        }
        bfs(1);
        top = 0;
        dfs(1, 1);
        printf("Case #%d:\n", Cas++);
        s.clear();
        int ans = 0;
        while (q--) {
            int op; int u; rd(op); rd(u);
            if (op == 1) {
                if (!s.count(u))
                {
                    s.insert(u);
                    if (s.size() > 1) 
                    {
                        int x = Up(1, p[u]), y = Low(p[u], n);
                        if (x == -1 || y == -1)
                        {
                            x = Low(1, n); y = Up(1, n);
                        }
                        x = fp[x]; y = fp[y];
                        ans += dis[u] - dis[Lca(x, u)] - dis[Lca(y, u)] + dis[Lca(x, y)];
                    }
                    change(p[u], 1);
                }
            }
            else {
                if (s.count(u)) 
                {
                    s.erase(u);
                    change(p[u], -1);
                    if (s.size())
                    {
                        int x = Up(1, p[u]), y = Low(p[u], n);
                        if (x == -1 || y == -1)
                        {
                            x = Low(1, n); y = Up(1, n);
                        }
                        x = fp[x]; y = fp[y];
                        ans -= dis[u] - dis[Lca(x, u)] - dis[Lca(y, u)] + dis[Lca(x, y)];
                    }
                }
            }
            pt(ans); puts("");
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值