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

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

#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. nyoj 还是回文

    还是回文 时间限制:2000 ms | 内存限制:65535 KB 难度:3 描述 判断回文串很简单,把字符串变成回文串也不难.现在我们增加点难度,给出一串字符(全部是小写字母),添加或删除一个字符, ...

  2. 使用Google 的 gson方式解析json

    gson支持解析的类型还是比较全面的,包括JavaBean,List<JavaBean>,List<String>,Map等,使用起来也是比较方便,下面根据代码示例给出总结: ...

  3. Microsoft dynamic sdk中join应该注意的问题.

    QueryExpression queryNextSeq = new QueryExpression { EntityName = "ep_prodoperationsequence&quo ...

  4. sts 和 lombok

    1.安装lombok.jar到sts.exe所在目录 如果是eclipse,需要放到eclipse.exe所在目录,同理myeclipse. 2.修改sts.ini配置使用lombok 如果是ecli ...

  5. emqtt 试用(三)mqtt 知识

    一.概念 MQTT 协议客户端库: https://github.com/mqtt/mqtt.github.io/wiki/libraries 例如,mosquitto_sub/pub 命令行发布订阅 ...

  6. Linux CentOS7.0 (02)修改主机名和ip地址

    一.主机名修改 1.查看命令 在CentOS中,有三种定义的主机名:静态的(static),瞬态的(transient),和灵活的(pretty). "静态"主机名也称为内核主机名 ...

  7. SpringBoot的注解:@SpringBootApplication注解 vs @EnableAutoConfiguration+@ComponentScan+@Configuration

    spring Boot开发者经常使用@Configuration,@EnableAutoConfiguration,@ComponentScan注解他们的main类, 由于这些注解如此频繁地一块使用( ...

  8. 如何彻底解决MySQL更改默认字符集以及字符乱码问题!!!

    在我们使用MySQL数据库时,字符乱码,对我们来说是一个很头疼的问题.今天笔者就来教大家如何彻底解决更改默认字符集以及字符乱码问题. 当我们使用压缩包进行MySQL安装后,系统会使用默认的字符集,这时 ...

  9. 一次完败的Release

    一次完败的Release 去年8月份加入一家创业公司,和原同事做VR相关的产品开发,到18年正月初七,总共release过两次,真正经理了一次从0到1的过程.第一次release产品初步成型,大概在1 ...

  10. JVMGC机制

    GC 是JVM的垃圾回收器.与C/C++不同,java程序员无需考虑太多内存分配的位置,更不用考虑内存释放的机制,java对象内存的申请和释放都有JVM托管.JVM的内存释放机制就是GC. GC的过程 ...