关闭

[CodeForces 593D]Happy Tree Party[LCA][路径压缩]

标签: LCA路径压缩
583人阅读 评论(0) 收藏 举报
分类:
题目链接:[CodeForces 593D]Happy Tree Party[LCA][路径压缩]

题意分析:

给出两个操作,1和2。

1代表查询结点a到结点b之间最短路径,将路径上的权值对y进行向下求整,输出结果。

2更改某个结点的权值

解题思路:

y最大1e18,对于除数为大于1的数字来说,最多除60次就可以让y变成0了。所以用lca不断除,当结果是0时就返回结果。

不过还要考虑除数为1的情况,这就会使得路径变得很长导致T了。所以要路径压缩一下。

个人感受:

比赛的时候知道LCA,但是觉得会T,没考虑过向下除不超过60次就变0了。

具体代码如下:

#include<cstdio>
#include<iostream>
#include<queue>
#define ll long long
#define pr(x) cout << #x << " = " << (x) << '\n';
using namespace std;

const int INF = 0x7f7f7f7f;
const int MAXN = 2e5 + 111;

struct Node{
    int v, id;
    ll w;
    Node(int _v, ll _w, int _id): v(_v), w(_w), id(_id) {}
};

int dep[MAXN], fa[MAXN], par[MAXN], point[MAXN]; // point:点所对应的边id
ll val[2 * MAXN];
vector<Node> G[MAXN];

int find(int x)
{
    return x == par[x] ? x : par[x] = find(par[x]);
}

void dfs(int u, int p, int d)
{
    dep[u] = d;
    fa[u] = p;
    for (int i = 0; i < G[u].size(); ++i)
    {
        Node &e = G[u][i];
        if (e.v != p)
        {
            val[e.v] = e.w; // 将点所对应的权值转换为以这个结点为结尾的边对应的权值来记录
            point[e.id] = e.v; // 用id来查找点
            dfs(e.v, u, d + 1);
        }
    }
}

ll lca(int u, int v, ll w)
{
    u = find(u), v = find(v);
    while (u != v) // 每次将较低的结点向上提升,不断除
    {
        if (dep[u] < dep[v]) swap(u, v);
        w /= val[u]; u = find(fa[u]);
        if (w == 0) return 0;
    }
    return w;
}

void update(int u) // 如果该点权值为一,那么就让它的祖先指向它的父亲结点
{
    par[u] = fa[u];
}

int main()
{
    int n, m, u, v, op;
    ll w;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) G[i].clear(), par[i] = i;
    for (int i = 1; i < n; ++i)
    {
        scanf("%d%d%I64d", &u, &v, &w);
        G[u].push_back(Node(v, w, i));
        G[v].push_back(Node(u, w, i));
    }

    dfs(1, -1, 0);

    for (int i = 2; i <= n; ++i) if (val[i] == 1) update(i);

    int a, b, p;
    ll y, c;
    while (m --)
    {
        scanf("%d", &op);
        if (op == 1)
        {
            scanf("%d%d%I64d", &a, &b, &y);
            printf("%I64d\n", lca(a, b, y));
        }
        else
        {
            scanf("%d%I64d", &p, &c);
            int v = point[p]; val[v] = c;
            if (c == 1) update(v);
        }
    }
    return 0;
}


0
0
查看评论

FZU 2207 以撒的结合(LCA+记录路径)

Problem Description小茗同学最近在认真地准备比赛,所以经常玩以撒的结合。《以撒的结合》是一款由Edmund McMillen,Florian Himsl 开发,并由Edmund McMillen最早于2011年09月29日发行的一款2D平面角色扮演、动作冒险类的独立游戏。游戏的角色...
  • qq_33183401
  • qq_33183401
  • 2017-06-05 18:35
  • 152

LCA 最近公共祖先 tarjan离线 总结 结合3个例题

在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解   LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点。也就是说,在两个点通往根的道路上,肯定会有公共的节点,我们就是要求找到公共的节点中,深度尽量深...
  • hnust_xiehonghao
  • hnust_xiehonghao
  • 2013-06-18 14:18
  • 10032

Magic Number LCA求路径点集的并

题意:给n个数(n 你可以根据n个数(题目中的a数组) 得到b数组。规则如下: PS:可以看出b[i]第i位一定为1 i+1 ~ n位一定为0 若b[i]的第j位为1,则满足条件的b[k]第j位都为1 再回给你一个询问数q,和另一个01串T(1的数量,输入会告诉哪些位置是1,将T分为q段,每一段...
  • EOD_realize
  • EOD_realize
  • 2017-06-04 10:55
  • 231

lca问题的完美解决和升级!!!——预处理+二分深搜

良好应用:2013noip提高组day1压轴题货车运输 思路:可以明显看出是最大生成树,然后可以想到寻找路径,结果就是路径上的最小值(因为是树,所以路径是唯一的!)             最后就是如何求路径最小值了,可以先求出lca,同时...
  • no1_terminator
  • no1_terminator
  • 2015-10-27 21:17
  • 445

codeforces 593D(并查集 + LCA)

题意不在描述. 首先我们注意到改变每个点的值时,只会变的更小,每次要除的数为1e18 , 由于log2(1e18) <= 60 .那么最多只需要除以至多60次大于等于2的数变回变成0,所以我们 只以任意一点为根建立有根树,并且在每次遍历一条链时进行压缩,当该路经值为1,应该被压缩,每次走到多余六...
  • playwfun
  • playwfun
  • 2015-11-09 10:19
  • 438

Codeforces Round #329 D Happy Tree Party(树链剖分)

题意:给出一棵树,每条边有一个权值,每次可以进行两种操作,第一种计算操作给出一个数y和结点u,v,计算y除以  从节点u到结点v之间所有数的商(向下取整),第二种操作是修改操作,将第i条边的权值修改为u。要求对于每一个询问输出结果。 思路:因为y分别除以(下取整)一条链上的所有数等价于y除...
  • u014664226
  • u014664226
  • 2015-11-05 16:09
  • 527

CodeForces 593D Happy Tree Party

Description Bogdan has a birthday today and mom gave him a tree consisting of n vertecies. For every edge of the tree i, some number...
  • jtjy568805874
  • jtjy568805874
  • 2016-11-24 23:14
  • 174

codeforces 593D happy tree party 树链剖分

/* 题目描述:给定一棵树及其边权,有两种操作 1 u v y 用y依次去除uv的公共路径上的每一条边的边权,注意这里的除法是整数的除法 2 x p 把第x条输入边的边权变为p 方法:容易证明,依次去除每一条边权,等于除以这条路径上所有边权的乘积,原因是前者相当于除一次保留...
  • jijijix
  • jijijix
  • 2016-11-19 10:54
  • 126

【13.91%】【codeforces 593D】Happy Tree Party

time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard output Bogdan has a birthday today and mom gave...
  • harlow_cheng
  • harlow_cheng
  • 2016-11-11 09:55
  • 119

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

#include #include #include #include #include #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; const int m...
  • diary_yang
  • diary_yang
  • 2015-11-06 15:00
  • 634
    个人资料
    • 访问:113756次
    • 积分:3347
    • 等级:
    • 排名:第11959名
    • 原创:228篇
    • 转载:8篇
    • 译文:0篇
    • 评论:29条
    联系我:
    最新评论