树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)
题意:
有n个点的一棵树,两种操作:
1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y;
2. 修改某个条边p的值为c
思路:
链上操作的问题,想树链剖分和LCT,对于第一种操作,因为是向下取整,考虑y除以路径上所有边乘积,即;对于第二种操作,就是线段树上的单点更新。因为给的是边的序号,首先每个id能知道对应的边值(ide[])和连接的点(idv[])。还有乘法溢出的处理,写成函数方便多了。
另外:
1. 用dfn来替换dep完全没有问题,那以后就用dfn吧。2. 第二次DFS,要先去重儿子的路,这样dfn[son[u]]=dfn[u]+1,son数组也省了。3. 代码debug水平有待提升。4. 树的建图用vector就行了,不需要邻接表(n-1条边)。
#include <bits/stdc++.h> typedef long long ll;
const int N = 2e5 + 5;
const ll INF = 2e18; std::vector<std::pair<int, int> > edges[N];
int n, m; int dfn[N], fa[N], son[N], sz[N], belong[N];
ll ide[N];
int idv[N];
int tim; inline ll mul(ll a, ll b) {
if (a != 0 && b > INF / a) return INF;
return a * b;
} void DFS2(int u, int chain) {
dfn[u] = ++tim;
belong[u] = chain;
if (son[u] != 0) {
DFS2 (son[u], chain);
}
for (auto e: edges[u]) {
int v = e.first;
if (v == fa[u] || v == son[u]) continue;
DFS2 (v, v);
}
} void DFS1(int u, int pa) {
sz[u] = 1;
fa[u] = pa;
for (auto e: edges[u]) {
int v = e.first, id = e.second;
if (v == pa) continue;
idv[id] = v;
DFS1 (v, u);
if (sz[v] > sz[son[u]]) son[u] = v;
sz[u] += sz[v];
}
} #define lson l, mid, o << 1
#define rson mid + 1, r, o << 1 | 1 ll val[N<<2]; void push_up(int o) {
val[o] = mul (val[o<<1], val[o<<1|1]);
} void tree_updata(int p, ll c, int l, int r, int o) {
if (l == r) {
val[o] = c;
return ;
}
int mid = l + r >> 1;
if (p <= mid) tree_updata (p, c, lson);
else tree_updata (p, c, rson);
push_up (o);
} ll tree_query(int ql, int qr, int l, int r, int o) {
if (ql <= l && r <= qr) {
return val[o];
}
int mid = l + r >> 1;
ll ret = 1;
if (ql <= mid) ret = mul (ret, tree_query (ql, qr, lson));
if (qr > mid) ret = mul (ret, tree_query (ql, qr, rson));
return ret;
} ll query(int a, int b) {
ll ret = 1;
int p = belong[a], q = belong[b];
while (p != q) {
if (dfn[p] < dfn[q]) {
std::swap (p, q);
std::swap (a, b);
}
ret = mul (ret, tree_query (dfn[p], dfn[a], 1, n, 1));
a = fa[p];
p = belong[a];
}
if (dfn[a] < dfn[b]) std::swap (a, b);
if (a != b) {
ret = mul (ret, tree_query (dfn[son[b]], dfn[a], 1, n, 1));
}
return ret;
} void modify(int id, ll c) {
tree_updata (dfn[idv[id]], c, 1, n, 1);
} void prepare() {
DFS1 (1, 0);
tim = 0;
DFS2 (1, 1);
for (int i=1; i<n; ++i) {
tree_updata (dfn[idv[i]], ide[i], 1, n, 1);
}
} int main() {
scanf ("%d%d", &n, &m);
for (int i=1; i<n; ++i) {
int u, v;
ll w;
scanf ("%d%d%I64d", &u, &v, &w);
ide[i] = w;
edges[u].push_back ({v, i});
edges[v].push_back ({u, i});
} prepare (); for (int i=0; i<m; ++i) {
int t, a, b;
ll c;
scanf ("%d%d", &t, &a);
if (t == 1) {
scanf ("%d%I64d", &b, &c);
printf ("%I64d\n", c / query (a, b));
} else {
scanf ("%I64d", &c);
modify (a, c);
}
}
return 0;
}
树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)的更多相关文章
- CF G. Indie Album 广义后缀自动机+树链剖分+线段树合并
这里给出一个后缀自动机的做法. 假设每次询问 $t$ 在所有 $s$ 中的出现次数,那么这是非常简单的: 直接对 $s$ 构建后缀自动机,随便维护一下 $endpos$ 大小就可以. 然而,想求 $t ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
随机推荐
- 执行mvn 报错 source-1.5 中不支持 diamond运算符
编译版本出现了问题 <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> < ...
- rpc-1-OSI模型
rpc-1-OSI模型 第一部分,网络7层协议 1. OSI模型: 开放通信系统互联网参考模型,是国际标准化组织(ISO),提出的一个,试图使各种计算机在世界范围内互连为网络的模式.(遵循这个模式,计 ...
- Python中函数、类、模块和包的调用
初学python阶段,大多数人对函数.类.模块和包的调用都搞得不是很清楚,这篇随笔就简单的进行说明. (1)函数 当函数定义好之后,可以直接调用. 比如:def summ(add1,add2),那么 ...
- RabbitMQ 集群安装过程详解
一.安装Erlang 1.rabbitMQ是基于erlang的,所以首先必须配置erlang环境. 从erlang官网下载 otp 18.3.下载链接:http://erlang.org/downlo ...
- git用法之常用命令[克隆、提交]
1.克隆/下载项目 1)git clone git@git.soydai.cn:liuxuewen/static-file-3.0.git 或者 2)git clone http://git.soyd ...
- VS2013 密钥 – 所有版本
Visual Studio Ultimate 2013 KEY(密钥):BWG7X-J98B3-W34RT-33B3R-JVYW9 Visual Studio Premium 2013 KEY(密钥) ...
- 【webGL】threejs常用的api
/*** 场景(scene) ***/ var scene = new THREE.Scene(); // 创建场景 scene.add(x); // 插入场景 /*** 相机(camera) *** ...
- Shell $? $* $@ 等含义
$0 ------>脚本名 $1 ------>传入的第一个参数值 $? ------>脚本执行的结果.成功==0,不成功==非0 $* ------>所有参数的内容 $@ - ...
- Http与Socket小谈
http与socket是网络编程中最为重要的概念,不管是客户端还是服务端,都是最为重要的部分,以下简述两者的关系和区别(个人见解). Http 定义 基于应用层的超文本传输协议.通常承载于TCP/IP ...
- Ajax文件上传