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

来源:互联网 发布:网络投资是真的吗 编辑:程序博客网 时间:2024/06/05 06:24
#include <iostream>#include <algorithm>#include <vector>#include <cstdio>#include <cstring>#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1using 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;}

0 0
原创粉丝点击