Codeforces 593D - Happy Tree Party(树链剖分)

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstring>

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;

const int maxn = 200020;
const long long INF = 1e18;
int n, m, total, edge_size;

int fa[maxn], pos[maxn], son[maxn], depth[maxn], _size[maxn], _top[maxn], edge_id[maxn];
long long seg_tree[maxn<<2], edge_value[maxn];

struct Edge
{
    int from, to;
    long long dist;
};
vector<Edge> edges;
vector<int> G[maxn];

void init()
{
    total = edge_size = 0;
    memset(son, -1, sizeof(son));
    for(int i=0; i<=n; i++) G[i].clear();
    edges.clear();
}

void AddEdge(int u, int v, long long w)
{
    edges.push_back((Edge){u, v, w});
    G[u].push_back(edge_size);
    edge_size++;
}

void DFS(int u, int pre, int deep)
{
    fa[u] = pre;
    depth[u] = deep;
    _size[u] = 1;
    for(int i=0; i<G[u].size(); i++)
    {
        Edge e = edges[G[u][i]];
        if(e.to == pre)     continue;

        DFS(e.to, u, deep+1);
        _size[u] += _size[e.to];
        if(son[u] == -1 || _size[e.to] > _size[son[u]])
        {
            son[u] = e.to;
        }
    }
}

void BuildTree(int u, int TOP)
{
    pos[u] = ++total;
    _top[u] = TOP;
    if(son[u] == -1)    return ;

    BuildTree(son[u], TOP);
    for(int i=0; i<G[u].size(); i++)
    {
        int v = edges[G[u][i]].to;
        if(v != fa[u] && v != son[u])
        {
            BuildTree(v, v);
        }
    }
}

long long Mul(long long a, long long b)
{
    if(a == 0 || b == 0) return 0;
    if(INF / a < b) return 0;
    return a * b;
}

void PushUp(int rt)
{
    seg_tree[rt] = Mul(seg_tree[rt<<1], seg_tree[rt<<1|1]);
}

void BuildSegTree(int l, int r, int rt)
{
    seg_tree[rt] = 1;
    if(l == r) return ;
    int m = (l + r) >> 1;
    BuildSegTree(lson);
    BuildSegTree(rson);
}

void Update(int p, long long val, int l, int r, int rt)
{
    if(l == r)
    {
        seg_tree[rt] = val;
        return ;
    }
    int m = (l + r) >> 1;
    if(p <= m) Update(p, val, lson);
    else Update(p, val, rson);
    PushUp(rt);
}

long long Query(int L, int R, int l, int r, int rt)
{
    if(L <= l && R >= r)
    {
        return seg_tree[rt];
    }
    int m = (l + r) >> 1;
    long long ret = 1;
    if(L <= m) ret = Mul(ret, Query(L, R, lson));
    if(R > m) ret = Mul(ret, Query(L, R, rson));
    return ret;
}

long long Calc(int u, int v)
{
    int f1 = _top[u], f2 = _top[v];
    long long ret = 1;
    while(f1 != f2)
    {
        if(depth[f1] < depth[f2])
        {
            swap(f1, f2);
            swap(u, v);
        }
        ret = Mul(ret, Query(pos[f1], pos[u], 1, n, 1));
        u = fa[f1];
        f1 = _top[u];
    }
    if(u == v) return ret;

    if(depth[u] > depth[v]) swap(u, v);
    ret = Mul(ret, Query(pos[son[u]], pos[v], 1, n, 1));
    return ret;
}

int main()
{
    while(cin>>n>>m)
    {
        init();
        int u, v;
        long long w;
        for(int i=1; i<n; i++)
        {
            scanf("%d%d%lld", &u, &v, &w);
            AddEdge(u, v, w);
            edge_id[i] = edge_size - 1;
            edge_value[i] = w;
            AddEdge(v, u, w);
        }
        DFS(1, 0, 0);
        BuildTree(1, 1);
        for(int i=1; i<n; i++)
        {
            Edge e = edges[edge_id[i]];
            if(depth[e.from] > depth[e.to]) edge_id[i] = pos[e.from];
            else edge_id[i] = pos[e.to];
        }
        BuildSegTree(1, n, 1);
        for(int i=1; i<n; i++)
        {
            Update(edge_id[i], edge_value[i], 1, n, 1);
        }
        for(int i=0; i<m; i++)
        {
            int op;
            scanf("%d", &op);
            if(op == 1)
            {
                scanf("%d%d%lld", &u, &v, &w);
                long long ans = Calc(u, v);
                if(ans == 0) puts("0");
                else printf("%lld\n", w / ans);
            }
            else
            {
                scanf("%d%lld", &u, &w);
                Update(edge_id[u], w, 1, n, 1);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(Codeforces 593D - Happy Tree Party(树链剖分))