题目链接

题意:就是给你一颗这样的树,用一个$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+并查集)的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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/ ...

  4. 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 ...

  5. 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 ...

  6. 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. ...

  7. 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 ...

  8. Codeforces Round #254 (Div. 2) B. DZY Loves Chemistry (并查集)

    题目链接 昨天晚上没有做出来,刚看题目的时候还把题意理解错了,当时想着以什么样的顺序倒,想着就饶进去了, 也被题目下面的示例分析给误导了. 题意: 有1-n种化学药剂  总共有m对试剂能反应,按不同的 ...

  9. Codeforces Round #260 (Div. 1) C. Civilization 树的中心+并查集

    题目链接: 题目 C. Civilization time limit per test1 second memory limit per test256 megabytes inputstandar ...

随机推荐

  1. 数据库_4_SQL介绍

    SQL SQL:Structured Query Language,结构化查询语言(数据已查询为主:99%是在进行查询操作)    what型语言,而非how型的语言. SQL分为三个部分: DDL: ...

  2. C基础:关于预处理宏定义命令

    为了程序的通用性,可以使用#define预处理宏定义命令,它的具体作用,就是方便程序段的定义和修改. 1.关于预定义替代 #define Conn(x,y) x##y#define ToChar(x) ...

  3. shell脚本,awk实现每个数字加1.

    [root@localhost add]# cat file [root@localhost add]# cat file|awk '{for(i=1;i<=NF;i++){$i+=1}}1' ...

  4. java集合测试类等

    package demo.mytest; import java.lang.ref.SoftReference;import java.lang.ref.WeakReference;import ja ...

  5. MySQL中数组的存储

    1. MySQL中以字符串的形式存储数组 MySQL中无数组类型,通常将数组元素按某个字符分割以字符串形式存储 1.1. 求数组中元素的个数 方法:按指定符号分割字符串,返回分割后的元素个数.方法很简 ...

  6. 文件操作-cp

    Linux cp命令 也是我们在实际使用中非常常用的一个命令,主要用来复制文件.文件夹等.今天就来给大家介绍下 cp命令 的使用. 转载自 https://www.linuxdaxue.com/lin ...

  7. Python变量、常量、数据类型

    1. 变量 变量是一种使用方便的占位符,用于引用计算机内存地址,该地址可以存储Script运行时可更改的程序信息.例如,可以创建一个名为ClickCount的变量来存储用户单击Web页面上某个对象的次 ...

  8. windows下升级pip失败,重新安装pip最新版本

    环境: python3.6.5 32bit,后改为python3.4.3 32bit pycharm2018旗舰版 问题: pycharm里的pip一直无法升级到10.0.1版本,在cmd中使用升级命 ...

  9. cs231n课程索引

    课程资源 课程官网 课程视频-youtube 课程视频-字幕版 官方笔记 官方笔记-中文版 课程作业参考答案

  10. luogu2483 【模板】k短路([SDOI2010]魔法猪学院)

    模板题 #include <iostream> #include <cstring> #include <cstdio> #include <queue> ...