/*
HYSBZ1036
树上有1-n个结点,每个节点都有一个权值w
操作 CHANGE u t:把结点u的权值改为t
QMAX u v:询问从点u到v的路径上的节点的最大权值
QSUM u v:询问从点u到v的路径上的结点的权值和
从点u到点v路径上的结点包括u,v本身 */
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAXN 30010
using namespace std;
struct Edge{
int to, next;
}edge[MAXN*];
int head[MAXN], tot;
int top[MAXN];//重链顶端
int fa[MAXN];//父亲
int deep[MAXN];//深度,root=1
int num[MAXN];//子节点数
int p[MAXN];//v在线段树中的位置
int fp[MAXN];
int son[MAXN];//重儿子
int pos;
void init(){
tot = ;
memset(head, -, sizeof(head));
pos = ;
memset(son, -, sizeof(son));
}
void addedge(int u, int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
//第一次dfs求fa,deep,son,num
void dfs1(int u, int pre, int d){
deep[u] = d;
fa[u] = pre;
num[u] = ;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if (v != pre){
dfs1(v, u, d+);
num[u]+=num[v];
if (son[u]==-||num[v]>num[son[u]])
son[u] = v;
}
}
}
//第二次dfs求top,p,用pos记数
void getpos(int u, int sp){//sp表示重链顶端
top[u] = sp;
p[u] = pos++;
fp[p[u]] = u;
if (son[u]==-)
return;
getpos(son[u], sp);//先把重儿子查到底
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;//轻儿子
if (v != son[u] && v != fa[u])
getpos(v, v);
}
} //线段树部分
struct Node{
int l, r;
int sum;
int Max;
}segTree[MAXN*];
inline void push_up(int i){
segTree[i].sum = segTree[i<<].sum + segTree[i<<|].sum;
segTree[i].Max = max(segTree[i<<].Max, segTree[i<<|].Max);
}
int s[MAXN];
void build(int i, int l, int r){
segTree[i].l = l;
segTree[i].r = r; if (l==r){
segTree[i].sum = segTree[i].Max = s[fp[l]];
return;
} int mid = l+r >> ;
build(i<<, l, mid);
build(i<<|, mid+, r);
push_up(i);
}
//更新线段树的第k个值为val
void update(int i, int k, int val){
if(segTree[i].l == k && segTree[i].r == k){
segTree[i].Max = segTree[i].sum = val;
return;
}
int mid = segTree[i].l + segTree[i].r >> ;
if (k <= mid)
update(i<<, k, val);
else
update(i<<|, k, val);
push_up(i);//单点更新后要重新计算Max和Sum
}
//查询[l,r]区间的最大值
int queryMax(int i, int l, int r){
if(segTree[i].l == l && segTree[i].r == r)
return segTree[i].Max;
int mid = segTree[i].l+segTree[i].r >> ;
if (r <= mid)
return queryMax(i<<, l, r);
else if (l > mid)
return queryMax(i<<|, l, r);
else
return max(queryMax(i<<, l, mid), queryMax(i<<|, mid+, r));
}
//查询[l,r]区间的和
int querySum(int i, int l, int r){
if(segTree[i].l==l && segTree[i].r == r)
return segTree[i].sum;
int mid = segTree[i].l+segTree[i].r>>;
if(r <= mid)
return querySum(i<<,l,r);
else if(l > mid)
return querySum((i<<)|,l,r);
else
return querySum(i<<, l, mid)+querySum(i<<|, mid+, r);
}
//查询u->v路径上结点的最大权值
int findMax(int u, int v){
int f1 = top[u], f2 = top[v];
int tmp = -;
while(f1!=f2){//不在同一条重链上时
if(deep[f1]<deep[f2]){
swap(u, v);
swap(f1, f2);
}
tmp = max(tmp, queryMax(, p[f1], p[u]));//把这一条链上的求出来
u = fa[f1];
f1 = top[u];
}
if (deep[u]>deep[v])
swap(u,v);
return
max(tmp, queryMax(, p[u], p[v])); }
//查询u->v路径上结点的权值
int findSum(int u, int v){
int f1 = top[u];
int f2 = top[v];
int tmp = ;
while(f1 != f2){
if (deep[f1] < deep[f2]){
swap(f1, f2);
swap(u, v);
}
tmp += querySum(, p[f1], p[u]);
u = fa[f1];
f1 = top[u];
}
if(deep[u]>deep[v])
swap(u, v);
return tmp + querySum(, p[u], p[v]);
} int main(){
int n;
int q;
char op[];
int u, v;
while(scanf("%d", &n)==){
init();
for(int i = ; i < n; i++){
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
for(int i = ; i <= n; i++)
scanf("%d", &s[i]); dfs1(,,);
getpos(,);
build(, , pos-); scanf("%d", &q);
while(q--){
scanf("%s%d%d", op, &u, &v);
if (op[]=='C')
update(, p[u], v);//单点修改
else if (strcmp(op, "QMAX")==)
printf("%d\n", findMax(u, v));//查询u->v路径上点权的最大值
else
printf("%d\n", findSum(u, v));//查询路径上点权的和
}
}
return ;
}

bzoj1036点权模板题的更多相关文章

  1. EOJ Monthly 2018.8 D. Delivery Service-树上差分(边权/边覆盖)(边权转点权)(模板题)

    D. Delivery Service 单测试点时限: 2.5 秒 内存限制: 512 MB EOJ Delivery Service Company handles a massive amount ...

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

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

  3. 洛谷 P3128 [USACO15DEC]最大流Max Flow-树上差分(点权/点覆盖)(模板题)

    因为徐州现场赛的G是树上差分+组合数学,但是比赛的时候没有写出来(自闭),背锅. 会差分数组但是不会树上差分,然后就学了一下. 看了一些东西之后,对树上差分写一点个人的理解: 首先要知道在树上,两点之 ...

  4. 【BZOJ1036】[ZJOI2008] 树的统计Count(一道可怕的模板题:树剖+线段树)

    点此看题面 题解 这真的只是一道模板题:一个树链剖分套上一个线段树(令我窒息的组合). 既然是模板题,那就直接上代码吧. 代码 #include<bits/stdc++.h> #defin ...

  5. [置顶] 小白学习KM算法详细总结--附上模板题hdu2255

    KM算法是基于匈牙利算法求最大或最小权值的完备匹配 关于KM不知道看了多久,每次都不能完全理解,今天花了很久的时间做个总结,归纳以及结合别人的总结给出自己的理解,希望自己以后来看能一目了然,也希望对刚 ...

  6. 【最大流ISAP】洛谷P3376模板题

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  7. POJ - 3264 线段树模板题 询问区间最大最小值

    这是线段树的一个模板题,给出一串数字,然后询问区间的最大最小值. 这个其实很好办,只需把线段树的节点给出两个权值,一个是区间的最小值,一个是区间的最大值,初始化为负无穷和正无穷,然后通过不断地输入节点 ...

  8. HDU 3966 Aragorn's Story(模板题)【树链剖分】+【线段树】

    <题目链接> 题目大意: 给定一颗带点权的树,进行两种操作,一是给定树上一段路径,对其上每个点的点权增加或者减少一个数,二是对某个编号点的点权进行查询. 解题分析: 树链剖分的模板题,还不 ...

  9. P1339 热浪 最短路径模板题

    这么naive的题面一看就是最短路模板题~~~ ok.首先是floyd算法,tts,记得把k放在最外面就行了. #include <cstdio> #include <cstring ...

随机推荐

  1. frp中的json模块

    预备知识 Go中的接口的数据结构可以分为两部分: 其中一部分指向或者存储了原始数据的值 另一部分指向或者存储了原始数据的类型描述符(其中包含类型,以及对应于接口中的方法) 所以大体上我们可以粗略的认为 ...

  2. Java需要强制捕获的异常

    Java编译器要求我们强制捕获Excetion,但不包括RuntimeException 不强制要求捕获Error和RuntimeException是因为,这两种异常我们程序一般无能为力,而其他Exc ...

  3. LVM基本概念及工作原理

    LVM基本概念及工作原理 背景知识: 一直困惑于LVM,特地找资料查了查,终于对LVM的概念和工作原理有了深入的理解.接下来记录下.新的技术出来必定是为了改变现有的不足,所以LVM的出现是由于对现有磁 ...

  4. javascript 体验定时器

    <script> // setInterval():循环定时器,循环执行 // setTimeout():炸弹定时器,只执行一次 //定义方法1:匿名函数 setInterval(func ...

  5. poi-对于word的操作(一)

    2017-03-02 15:17:30 使用的jar包是poi 3.13 实现对word的存入,字体.颜色.大小的控制 测试类: package poi.test; public class Word ...

  6. Java SE之正则表达式Demo

    @Test public void regex() {//匹配教务系统课程 // String content = "公共机座 (1-10)".replaceAll(" ...

  7. luogu P3924 康娜的线段树

    题面传送门 我们可以画图找规律 这里没图,要看图可以去看M_sea dalao的题解(逃 可以发现单个节点\(i\)对答案的贡献为该节点的点权\(*\frac{1}{2^{dep_i}}\)(\(de ...

  8. String split方法与Guava Splitter用法区别

    String split方法与Guava Splitter用法区别 今天同事写了一段使用String split方法的代码,如下所示,同事期望得到的是字符"1",但是没想到却得到空 ...

  9. JS浮点数运算Bug的解决办法

    方法一:重写浮点运算的函数 //除法函数,用来得到精确的除法结果 //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显.这个函数返回较为精确的除法结果. //调用:acc ...

  10. Windows Server 2008 R2 服务器系统安装图文教程

    https://www.jb51.net/os/535658.html http://www.machenike.com/article.php?id=207