码迷,mamicode.com
首页 > 其他好文 > 详细

Problem 2082 过路费树链剖分

时间:2014-11-06 01:54:25      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   color   os   for   sp   div   on   

裸题直接搞。

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

 

Problem 2082 过路费树链剖分

标签:style   blog   io   color   os   for   sp   div   on   

原文地址:http://www.cnblogs.com/yigexigua/p/4077710.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!