Problem 2082 过路费树链剖分

裸题直接搞。

#include<iostream>

#include<cstdio>

#include<cstring>

#include<map>

#include<vector>

#include<stdlib.h>

using namespace std;

#define lson l,mid,rt<<1

#define rson mid+1,r,rt<<1|1

typedef long long LL;

const LL maxn = 55555;

LL head[maxn];

LL len, z;

struct Node

{

    LL next; LL to;

}e[maxn * 2];

LL top[maxn], son[maxn];

LL father[maxn];

LL size[maxn]; LL pos[maxn];

LL deep[maxn];

LL sum[maxn << 2];

LL edge[maxn][10];



void add(LL from, LL to)

{

    e[len].to = to;

    e[len].next = head[from];

    head[from] = len++;

}



void init(LL x)

{

    size[x] = 1; son[x] = 0;

    for (LL i = head[x]; i != -1; i = e[i].next){

        LL cc = e[i].to;

        if (father[x] == cc) continue;

        father[cc] = x; deep[cc] = deep[x] + 1;

        init(cc);

        size[x] += size[cc];

        if (size[son[x]] < size[cc])son[x] = cc;

    }

}



void dfs(LL x, LL tp)

{

    pos[x] = ++z; top[x] = tp;

    if (son[x]) dfs(son[x], tp);

    for (LL i = head[x]; i != -1; i = e[i].next){

        LL cc = e[i].to;

        if (cc == father[x] || cc == son[x]) continue;

        dfs(cc, cc);

    }

}





void build(LL l, LL r, LL rt)

{

    sum[rt] = 0;

    if (l == r) return;

    LL mid = (l + r) >> 1;

    build(lson); build(rson);

}



void up(LL rt)

{

    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];

}



void update(LL key, LL ans, LL l, LL r, LL rt)

{

    if (l == r){

        sum[rt] = ans; return;

    }

    LL mid = (l + r) >> 1;

    if (key <= mid) update(key, ans, lson);

    else update(key, ans, rson);

    up(rt);

}



LL ask(LL L, LL R, LL l, LL r, LL rt)

{

    if (L <= l&&r <= R) return sum[rt];

    LL mid = (l + r) >> 1;

    LL ans = 0;

    if (L <= mid) ans += ask(L, R, lson);

    if (R > mid) ans += ask(L, R, rson);

    return ans;

}



LL gao(LL x, LL y)

{

    LL ans = 0;

    LL fx = top[x]; LL fy = top[y];

    while (fx != fy){

        if (deep[fx] < deep[fy]){

            swap(x, y); swap(fx, fy);

        }

        ans += ask(pos[fx], pos[x], 1, z, 1);

        x = father[fx]; fx = top[x];

    }

    if (x == y) return ans;

    if (deep[x]>deep[y]) swap(x, y);

    ans += ask(pos[son[x]], pos[y], 1, z, 1);

    return ans;

}





int main()

{

    LL a, b, c;

    LL n, m;

    while (cin >> n >> m){

        memset(head, -1, sizeof(head));

        len = 0; z = 0;

        for (LL i = 1; i < n; i++){

            scanf("%I64d%I64d%I64d", &edge[i][0], &edge[i][1], &edge[i][2]);

            add(edge[i][0], edge[i][1]); add(edge[i][1], edge[i][0]);

        }

        deep[1] = 1;

        init(1); dfs(1, 1); build(1, z, 1);

        for (LL i = 1; i < n; i++){

            LL a = edge[i][0]; LL b = edge[i][1]; LL c = edge[i][2];

            if (deep[a]>deep[b]) swap(edge[i][0], edge[i][1]);

            update(pos[edge[i][1]], c, 1, z, 1);

        }

        for (LL i = 0; i < m; i++){

            scanf("%I64d%I64d%I64d", &a, &b, &c);

            if (a == 0){

                edge[b][2] = c;

                update(pos[edge[b][1]], c, 1, z, 1);

            }

            else{

                LL t = gao(b, c);

                printf("%I64d\n", t);

            }

        }

    }

    return 0;

}

 

你可能感兴趣的:(em)