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

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

#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. Flask 部署和分发

    到目前为止,启动Flask应用都是通过"app.run()"方法,在开发环境中,这样固然可行,不过到了生产环境上,势必需要采用一个健壮的,功能强大的Web应用服务器来处理各种复杂情 ...

  2. Visual Studio 开发工具常用的插件

    转载自落日故乡  http://www.spersky.com/post/vsPlugins.html 该博客中收集整理归纳了若干个常用的vs插件,比如高亮显示当前选择,垂直辅助线,折叠代码等等,具体 ...

  3. JAVA_SE基础——45.基本类型变量.值交换[独家深入解析]

    需求:定义一个函数交换两个基本类型变量的值. 相信看过我前面的文章的同学都应该看的懂我以下的代码: class Demo2 { public static void main(String[] arg ...

  4. 安装 go 语言环境

    操作系统: CentOS 6.9_x64 go语言版本: 1.8.3 安装go 这里直接安装二进制,其它方式请自行搜索. 1.下载并安装go 命令如下: ? 1 2 3 wget https://st ...

  5. 新概念英语(1-101)A Card From Jimmy

    Lesson 101 A card from Jimmy 吉米的明信片 Listen to the tape then answer this question. Does Grandmother s ...

  6. Linux CentOS7.0 (03)安装验证 docker

    一.安装docker 1.升级 Linux 的软件包和内核 sudo yum update 2.安装 docker (1) sudo yum install docker  (2).验证docker安 ...

  7. Spring Security 入门(1-3-1)Spring Security - http元素 - 默认登录和登录定制

    登录表单配置 - http 元素下的 form-login 元素是用来定义表单登录信息的.当我们什么属性都不指定的时候 Spring Security 会为我们生成一个默认的登录页面. 如果不想使用默 ...

  8. 阿里云下Linux服务器安装Mysql、mongodb

    阿里云下Linux服务器安装Mysql.mongodb 一.MySQL的安装和配置 1.安装rpm包 rpm -Uvh http://dev.mysql.com/get/mysql-community ...

  9. python/socket编程之粘包

    python/socket编程之粘包 粘包 只有TCP有粘包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 发送端可以是1k,1k的发送数据而接受端的应用程序可以2k,2k的提 ...

  10. A、B同时打开一个页面进行同一条数据库记录进行修改,A修改完成后提交表单,A修改的数据保存完成后;当B也修改完成后,提交数据进行数据修改。此时B修改的内容会覆盖A修改的内容,请问如何避免?

    A.B同时打开一个页面进行数据中的一条数据进行修改,A修改完成后提交表单,数据修改保存完成后B开始页面也修改完成,开始提交进行修改.此时B修改的内容会覆盖A的内容,请问如何避免? 通过搜索和我个人总结 ...