实现了路径修改,子树查询,及换根。

换根其实很简单,分三种情况讨论,画画图就明白了。

#include <cstdio>
#include <algorithm>
using namespace std;
#define m ((L+R)>>1)
#define lc o<<1
#define rc o<<1|1
#define ls lc,L,m
#define rs rc,m+1,R const int N = , M = ;
int n,q,e,x,y,z,op,sd,tt;
int a[N],d[N],f[N],p[N],s[N],bg[N],ed[N],sz[N],tp[N],hd[N],nxt[M],to[M],v[N<<],mn[N<<];
void add(int x, int y) {to[++e] = y, nxt[e] = hd[x], hd[x] = e;} void dfs(int x) {
int mx = ; sz[x] = ;
for(int i = hd[x]; i; i = nxt[i]) if(!d[to[i]]) {
d[to[i]] = d[x]+, f[to[i]] = x, dfs(to[i]), sz[x] += sz[to[i]];
if(sz[to[i]] > mx) mx = sz[to[i]], s[x] = to[i];
}
}
void dfs2(int x) {
bg[x] = ++tt, p[tt] = x;
if(s[x]) tp[s[x]] = tp[x], dfs2(s[x]);
for(int i = hd[x]; i; i = nxt[i]) if(to[i] != f[x] && to[i] != s[x])
tp[to[i]] = to[i], dfs2(to[i]);
ed[x] = tt;
} void bd(int o, int L, int R) {
if(L == R) {mn[o] = a[p[L]]; return;}
bd(ls), bd(rs), mn[o] = min(mn[lc], mn[rc]);
}
void pd(int o) {
if(!v[o]) return;
mn[lc] = mn[rc] = v[o], v[lc] = v[rc] = v[o], v[o] = ;
}
void gai(int o, int L, int R, int l, int r, int x) {
if(L >= l && R <= r) {v[o] = mn[o] = x; return;}
pd(o);
if(l <= m) gai(ls, l, r, x); if(r > m) gai(rs, l, r, x);
mn[o] = min(mn[lc], mn[rc]);
}
int qry(int o, int L, int R, int l, int r) {
if(L >= l && R <= r) return mn[o];
pd(o);
if(r <= m) return qry(ls, l, r); if(l > m) return qry(rs, l, r);
return min(qry(ls, l, r), qry(rs, l, r));
} void upd(int x, int y, int z) {
while(tp[x]^tp[y]) {
if(d[tp[x]] < d[tp[y]]) swap(x, y);
gai(, , n, bg[tp[x]], bg[x], z), x = f[tp[x]];
}
if(d[x] < d[y]) swap(x, y);
gai(, , n, bg[y], bg[x], z);
} int main() {
scanf("%d%d", &n, &q);
for(int i = ; i < n; i++) scanf("%d%d", &x, &y), add(x, y), add(y, x);
for(int i = ; i <= n; i++) scanf("%d", &a[i]);
scanf("%d", &sd), d[sd] = , tp[sd] = sd, dfs(sd), dfs2(sd), bd(, , n);
while(q--) {
scanf("%d%d", &op, &x);
if(op == ) sd = x;
else if(op == ) scanf("%d%d", &y, &z), upd(x, y, z);
else {
if(sd == x) printf("%d\n", mn[]);
else if(bg[x] > bg[sd] || ed[x] < bg[sd]) printf("%d\n", qry(,,n,bg[x],ed[x]));
else {
for(int i = hd[x]; i; i = nxt[i])
if(to[i] != f[x] && bg[to[i]] <= bg[sd] && ed[to[i]] >= bg[sd]) {
int ans = qry(,,n,,bg[to[i]]-);
if(ed[to[i]]^n) ans = min(ans, qry(,,n,ed[to[i]]+,n));
printf("%d\n", ans);
break;
}
}
}
}
return ;
}

树链剖分模板(BZOJ3083)的更多相关文章

  1. BZOJ 2243 染色 | 树链剖分模板题进阶版

    BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...

  2. 算法复习——树链剖分模板(bzoj1036)

    题目: 题目背景 ZJOI2008 DAY1 T4 题目描述 一棵树上有 n 个节点,编号分别为 1 到 n ,每个节点都有一个权值 w .我们将以下面的形式来要求你对这棵树完成一些操作:I.CHAN ...

  3. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  4. bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题

    [ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...

  5. BZOJ 1036 树的统计Count 树链剖分模板题

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1036 题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将 ...

  6. BZOJ 1036 [ZJOI2008]树的统计Count | 树链剖分模板

    原题链接 树链剖分的模板题:在点带权树树上维护路径和,最大值和单点修改 这里给出几个定义 以任意点为根,然后记 size (u ) 为以 u 为根的子树的结点个数,令 v 为 u 所有儿子中 size ...

  7. bzoj1036 树的统计 树链剖分模板

    题意:给出树上任意两点,求路径上的值的和与最大值,带单点修改操作 树链剖分思路: 1.对树进行dfs求出点的深度和父亲节点,然后求出轻重儿子(重儿子就是点最多的那个子树,其余都是轻儿子),用一个son ...

  8. 洛谷 P3384 树链剖分(模板题)

    题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...

  9. QTREE 树链剖分---模板 spoj QTREE

    <树链剖分及其应用> 一文讲得非常清楚,我一早上就把他学会了并且A了这题的入门题. spoj QTREE 题目: 给出一棵树,有两种操作: 1.修改一条边的边权. 2.询问节点a到b的最大 ...

随机推荐

  1. android之SVG制作与应用

    文章解析及例子:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0825/3362.html 工具:Photoshop CC+sv ...

  2. VS系列控制台闪退解决

    查阅--->总结-->实践--> 按红色标识走 ,完美解决! 至此,完美解决:原理不深究:

  3. 个人技术博客(alpha)

    APP的权限校验不同于web网页端,web一般使用session记录用户的状态信息,而app则使用token令牌来记录用户信息.有这样一个场景,系统的数据量达到千万级,需要几台服务器部署,当一个用户在 ...

  4. JAVA_SE基础——52.匿名内部类

    电信的电箱烧了,害我断了2天网,真拿命,耽误了 Java匿名内部类的总结: 没有名字的内部类.就是内部类的简化形式.一般只用一次就可以用这种形式.匿名内部类其实就是一个匿名子类对象.想要定义匿名内部类 ...

  5. LeetCode & Q283-Move Zeroes-Easy

    Array Two Pointers Description: Given an array nums, write a function to move all 0's to the end of ...

  6. Mego(1) - NET中主流ORM框架性能对比

    从刚刚开始接触ORM到现在已有超过八年时间,用过了不少ORM框架也了解了不少ORM框架,看过N种关于ORM框架的相关资料与评论,各种言论让人很难选择.在ORM的众多问题中最突出的问题是关于性能方面的问 ...

  7. 剑指offer-两个链表的第一个公共节点

    题目描述 输入两个链表,找出它们的第一个公共结点. 解题思路 分析可得如果两个链表有公共节点,那么公共节点出现在两个链表的尾部,即从某一节点开始,两链表之后的节点全部相等.可以首先遍历两个链表得出各自 ...

  8. 增加Linux虚拟机的硬盘空间

    原配置为40G,现需要增加到60G,操作方法如下: 一.虚拟机关机,在编辑设置里调整硬盘空间到60G 二.虚拟机开机,扩展硬盘空间 1.安装gparted,命令如下 sudo apt-get inst ...

  9. ELK学习总结(3-1)elk的基本查询

    基本查询:内置条件 组合查询:组合基本查询 过滤:查询同时,通过filter筛选数据 准备工作  GET /library/books/_mget { "ids":["1 ...

  10. 从感知机到 SVM,再到深度学习(一)

        在上篇博客中提到,如果想要拟合一些空间中的点,可以用最小二乘法,最小二乘法其实是以样例点和理论值之间的误差最小作为目标.那么换个场景,如果有两类不同的点,而我们不想要拟合这些点,而是想找到一条 ...