/*
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. Problems you may meet

    一.正确安装sklearn却提示No module named 'sklearn.lda' It seems that you have installed a newer version of sk ...

  2. 即将上线的Hive服务器面临的一系列填坑笔记

    即将上线的Spark服务器面临的一系列填坑笔记 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.18/10/19 16:36:31 WARN metastore.ObjectSt ...

  3. js格式化日期工具类

    就是一个工具类  开箱即用 传进一个指定的参数,格式化 //将时间戳格式化 function getMyDate(time){ if(typeof(time)=="undefined&quo ...

  4. CodeForces-915C Permute Digits

    C. Permute Digits time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  5. digest 词根 gest

    digest  /ˈdaɪdʒest/: to change food that you have just eaten into substances that your body can use; ...

  6. Linux - openssl 加密

    openssl rand 15 -base64 # 口令生成 openssl sha1 filename # 哈希算法校验文件 openssl md5 filename # MD5校验文件 opens ...

  7. Java SE之初探反射机制

    [Keywords]:Java,Hibernate,虚拟机,框架,SQL [Abstract]:   反射的概念:所谓的反射就是java语言在运行时拥有一项自观的能力,反射使您的程序代码能够得到装载到 ...

  8. django错误笔记(xadmin)——AttributeError: 'Settings' object has no attribute 'TEMPLATE_CONTEXT_PROCESSORS'

    使用Xadmin,执行makemigrations和migrate时运行报错提示: AttributeError: 'Settings' object has no attribute 'TEMPLA ...

  9. php 全局变量问题

    当在函数里通过require_once包含另外php文件. 而另外php文件包含了另外php文件,而该php文件的函数需要另外的php文件. 例子: installment_maintenance_s ...

  10. 一分钟了解contextlib模块

    cobtextlib模块用于简化上下文管理器,其内置装饰漆@contextmanager,我们通过编写一个被contextmanager装饰的generator来简化上下文管理. from conte ...