Codeforces Round #329 (Div. 2) D. Happy Tree Party(LCA+并查集)
题目链接
题意:就是给你一颗这样的树,用一个$y$来除以两点之间每条边的权值,比如$3->7$,问最后的y的是多少,修改操作是把权值变成更小的。

这个$(y<=10^{18})$除的权值如果是$>=2$,那么最多除60几次就变成0了,问题关键是路径上会有好多1存在,这时候我们可以用并查集把他们并到一块,这样就能跳着查了。
具体查法:
从$u$到$LCA(u,v)$,路径上除一遍。
从$v$到$LCA(u,v)$,路径上除一遍。
修改操作如果变成1,就与前面的点合并。
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std; typedef long long ll;
const int maxn = 2e5 + ;
///加边
int cnt = , h[maxn];
struct edge
{
int to, pre;
ll v;
} e[maxn << ];
void add(int from, int to, ll v)
{
cnt++;
e[cnt].pre = h[from]; ///5-->3-->1-->0
e[cnt].to = to;
e[cnt].v = v;
h[from] = cnt;
}
///LCA
int dist[maxn];
int dep[maxn];
int anc[maxn][]; ///2分的父亲节点
ll len[maxn];
void dfs(int u, int fa)
{
for(int i = h[u]; i; i = e[i].pre)
{
int v = e[i].to;
if(v == fa) continue;
dist[v] = dist[u] + e[i].v;
dep[v] = dep[u] + ;
anc[v][] = u;
len[v] = e[i].v;
dfs(v, u);
}
}
void LCA_init(int n)
{
for(int j = ; ( << j) < n; j++)
for(int i = ; i <= n; i++) if(anc[i][j-])
anc[i][j] = anc[anc[i][j-]][j-];
}
int LCA(int u, int v)
{
int log;
if(dep[u] < dep[v]) swap(u, v);
for(log = ; ( << log) < dep[u]; log++);
for(int i = log; i >= ; i--)
if(dep[u] - ( << i) >= dep[v]) u = anc[u][i];
if(u == v) return u;
for(int i = log; i >= ; i--)
if(anc[u][i] && anc[u][i] != anc[v][i])
u = anc[u][i], v = anc[v][i];
return anc[u][];
}
int fa[maxn];
int Find(int x)
{
if(x == fa[x]) return x;
return fa[x] = Find(fa[x]);
}
int main()
{
int n, m; scanf("%d %d", &n, &m);
cnt = ;
for(int i = ; i <= n; i++) h[i] = ;
for(int i = ; i <= n - ; i++)
{
int u, v;
ll w; scanf("%d %d %lld", &u, &v, &w);
add(u, v, w), add(v, u, w);
}
///LCA初始化
dfs(, );
LCA_init(n);
///并查集初始化
for(int i = ; i <= n; i++) fa[i] = i;
while(m--)
{
int op, a, b, p;
ll c, y;
scanf("%d", &op);
if(op == )
{
scanf("%d %d %lld", &a, &b, &y);
int fp = LCA(a, b);
a = Find(a);
while(dep[a] > dep[fp] && y > 0LL)
{
if(len[a] == 1LL)
{
fa[a] = anc[a][];
a = Find(a);
}
else
{
y /= len[a];
a = Find(anc[a][]);
}
}
b = Find(b);
while(dep[b] > dep[fp] && y > 0LL)
{
if(len[b] == 1LL)
{
fa[b] = anc[b][];
b = Find(b);
}
else
{
y /= len[b];
b = Find(anc[b][]);
}
}
printf("%lld\n", y);
}
else
{
scanf("%d %lld", &p, &c);
int u = e[p * ].to, v = e[(p * ) ^ ].to;
if(u == anc[v][])
{
len[v] = c;
if(c == 1LL)
{
fa[v] = u;
}
}
else
{
len[u] = c;
if(c == 1LL)
{
fa[u] = v;
}
}
}
}
return ;
}
Codeforces Round #329 (Div. 2) D. Happy Tree Party(LCA+并查集)的更多相关文章
- Codeforces Round #329 (Div. 2) D. Happy Tree Party LCA/树链剖分
D. Happy Tree Party Bogdan has a birthday today and mom gave him a tree consisting of n vertecie ...
- Codeforces Round #396 (Div. 2) D. Mahmoud and a Dictionary 并查集
D. Mahmoud and a Dictionary 题目连接: http://codeforces.com/contest/766/problem/D Description Mahmoud wa ...
- Codeforces Round #250 (Div. 1) B. The Child and Zoo 并查集
B. The Child and Zoo Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/438/ ...
- Codeforces Round #360 (Div. 1) D. Dividing Kingdom II 暴力并查集
D. Dividing Kingdom II 题目连接: http://www.codeforces.com/contest/687/problem/D Description Long time a ...
- Codeforces Round #329 (Div. 2) D. Happy Tree Party 树链剖分
D. Happy Tree Party Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/593/p ...
- Codeforces Round #212 (Div. 2) D. Fools and Foolproof Roads 并查集+优先队列
D. Fools and Foolproof Roads You must have heard all about the Foolland on your Geography lessons. ...
- Codeforces Round #376 (Div. 2) A B C 水 模拟 并查集
A. Night at the Museum time limit per test 1 second memory limit per test 256 megabytes input standa ...
- Codeforces Round #254 (Div. 2) B. DZY Loves Chemistry (并查集)
题目链接 昨天晚上没有做出来,刚看题目的时候还把题意理解错了,当时想着以什么样的顺序倒,想着就饶进去了, 也被题目下面的示例分析给误导了. 题意: 有1-n种化学药剂 总共有m对试剂能反应,按不同的 ...
- Codeforces Round #260 (Div. 1) C. Civilization 树的中心+并查集
题目链接: 题目 C. Civilization time limit per test1 second memory limit per test256 megabytes inputstandar ...
随机推荐
- 剑指offer44 扑克牌顺序
注意一个边界条件:必须是连续的,如果前后两个数是一样的也不满足条件 class Solution { public: bool IsContinuous( vector<int> numb ...
- python之数据类型补充
1. capitalize (首字母大写) 例题: s = "alex wusir" s1 = s.capitalize() # 格式 print(s1) ''' 输出结果 Ale ...
- Vue之父子组件的通信
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue父组件获取子组件页面的数组 以城市三级联动为例
父组件调用子组件 <Cselect ref="registerAddress"></Cselect> import Cselect from '../../ ...
- [LUOGU] P1880 [NOI1995]石子合并
题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- perl学习之裸字
use strict包含3个部分.其中之一(use strict "subs")负责禁止乱用的裸字. 这是什么意思呢? 如果没有这个限制,下面的代码也可以打印出"hell ...
- perl学习之子程序
一.定义子程序即执行一个特殊任务的一段分离的代码,它可以使减少重复代码且使程序易读.PERL中,子程序可以出现在程序的任何地方.定义方法为:sub subroutine{statements;}二.调 ...
- django第11天(分页器)
django第11天分页器 分页模块 批量插入数据 book_list = [] #先生成对象 for i in range(100): book = Book(name = 'book%s'%i,p ...
- 剑指Offer(书):对称的二叉树
题目:请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. boolean isSymmetrical(TreeNode pRoot) { r ...
- 为什么我打的jar包没有注解?
本文来自网易云社区 作者:王飞 一.前言 一切问题的起源就是来自一个问题"为什么我打的jar包没有注解?",带着这个疑问查了一圈资料,原来问题主要是在没有将源码中的注释进行抽取打包 ...