洛谷P4114 Qtree1
标签
- 树链剖分
- 边权化点权
简明题意
- 给一颗树,给出边权,需要支持两种操作:
- 修改:将第i条边权改为c
- 查询:查询u-v的路径中权值最大值
思路
- 首先化边权为点权是必须的。然后
- 修改操作:
单点修改,直接改就行了 - 查询操作:
由于化边权为点权了,对于u-v的路径,我们直接去掉LCA(u,v)再查就是正确答案了。具体怎么去掉呢?直接在查询之前,将LCA(u,v)置为无穷小,查完再还原就可以了
- 修改操作:
注意事项
- 将LCA(u,v)置为无穷小时,记得用change函数去修改,不要直接在w上修改
总结
- 永远不要对w操作…
AC代码
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 10;
const int inf = -2e9;
struct Edge
{
int v, w;
Edge(int v, int w) : v(v), w(w) {
}
};
int n, a[maxn];
vector<Edge> g[maxn];
pair<int, int> rec[maxn];
int dep[maxn], fa[maxn], siz[maxn], son[maxn];
void dfs1(int u, int f, int deep, int w)
{
dep[u] = deep;
fa[u] = f;
siz[u] = 1;
a[u] = w;
int max_son = -1;
for (auto& v : g[u])
if (v.v != f)
{
dfs1(v.v, u, deep + 1, v.w);
siz[u] += siz[v.v];
if (siz[v.v] > max_son)
max_son = siz[v.v], son[u] = v.v;
}
}
int top[maxn