题目:

题目背景

ZJOI2008 DAY1 T4

题目描述

一棵树上有 n 个节点,编号分别为 1 到 n ,每个节点都有一个权值 w 。
我们将以下面的形式来要求你对这棵树完成一些操作:
I.CHANGE u t :把结点 u 的权值改为 t ;
II.QMAX u v :询问从点 u 到点 v 的路径上的节点的最大权值;
III.QSUM u v :询问从点 u 到点 v 的路径上的节点的权值和。

注意:从点 u 到点 v 的路径上的节点包括 u 和 v 本身。

输入格式

输入第一行为一个整数 n ,表示节点的个数。
接下来 n–1 行,每行 2 个整数 a 和 b ,表示节点 a 和节点 b 之间有一条边相连。
接下来 n 行,每行一个整数,第 i 行的整数 wi 表示节点 i 的权值。
接下来 1 行,为一个整数 q ,表示操作的总数。
接下来 q 行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。

输出格式

对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

样例数据 1

输入  [复制]

 


1 2 
2 3 
4 1 
4 2 1 3 
12 
QMAX 3 4 
QMAX 3 3 
QMAX 3 2 
QMAX 2 3 
QSUM 3 4 
QSUM 2 1 
CHANGE 1 5 
QMAX 3 4 
CHANGE 3 6 
QMAX 3 4 
QMAX 2 4 
QSUM 3 4

输出





10 




16

备注

【数据范围】
对于 100% 的数据,保证1<=n<=30000;0<=q<=200000;中途操作中保证每个节点的权值 w 在 -30000 到 30000 之间。

方法:

树链剖分模板题;

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=3e4+;
const int inf=1e+;
int n,Q;
int first[N],next[N*],go[N*];
int size[N],top[N],father[N],pos[N],idx[N],deep[N],tot,son[N],val[N];
int summ[N*],maxx[N*];
char st[]; inline void combin(int u,int v)
{
next[++tot]=first[u],first[u]=tot,go[tot]=v;
next[++tot]=first[v],first[v]=tot,go[tot]=u;
} inline void dfs1(int u)
{
size[u]=;
for(int e=first[u],v;e;e=next[e])
{
if((v=go[e])==father[u]) continue;
father[v]=u;
deep[v]=deep[u]+;
dfs1(v);
size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
} inline void dfs2(int u)
{
if(son[u])
{
idx[pos[son[u]]=++tot]=son[u];
top[son[u]]=top[u];
dfs2(son[u]);
}
for(int e=first[u],v;e;e=next[e])
{
if((v=go[e])==father[u]||v==son[u]) continue;
idx[pos[v]=++tot]=v;
top[v]=v;
dfs2(v);
}
} inline void pre()
{
dfs1();
top[]=pos[]=idx[]=tot=;
dfs2();
} inline void build(int k,int l,int r)
{
if(l==r)
{
summ[k]=maxx[k]=val[idx[l]];
return;
}
int mid=(l+r)/;
build(k*,l,mid);
build(k*+,mid+,r);
summ[k]=summ[k*]+summ[k*+];
maxx[k]=max(maxx[k*],maxx[k*+]);
} inline void modify(int k,int l,int r,int p,int v)
{
if(l==r)
{
summ[k]=maxx[k]=v;
return;
}
int mid=(l+r)/;
if(p<=mid) modify(k*,l,mid,p,v);
else modify(k*+,mid+,r,p,v);
summ[k]=summ[k*]+summ[k*+];
maxx[k]=max(maxx[k*],maxx[k*+]);
} inline int querymax(int k,int l,int r,int x,int y)
{
if(l>=x&&r<=y)
return maxx[k];
int mid=(l+r)/,res=-inf;
if(x<=mid) res=querymax(k*,l,mid,x,y);
if(y>mid) res=max(res,querymax(k*+,mid+,r,x,y));
return res;
} inline int querysum(int k,int l,int r,int x,int y)
{
if(l>=x&&r<=y)
return summ[k];
int mid=(l+r)/,res=;
if(x<=mid) res+=querysum(k*,l,mid,x,y);
if(y>mid) res+=querysum(k*+,mid+,r,x,y);
return res;
} inline int pathmax(int u,int v)
{
if(top[u]!=top[v])
{
if(deep[top[u]]<deep[top[v]]) swap(u,v);
return max(pathmax(father[top[u]],v),querymax(,,n,pos[top[u]],pos[u]));
}
if(deep[u]>deep[v]) swap(u,v);
return querymax(,,n,pos[u],pos[v]);
} inline int pathsum(int u,int v)
{
if(top[u]!=top[v])
{
if(deep[top[u]]<deep[top[v]]) swap(u,v);
return pathsum(father[top[u]],v)+querysum(,,n,pos[top[u]],pos[u]);
}
if(deep[u]>deep[v]) swap(u,v);
return querysum(,,n,pos[u],pos[v]);
} int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
scanf("%d",&n);
int u,v;
for(int i=;i<n;i++)
{
scanf("%d%d",&u,&v);
combin(u,v);
}
for(int i=;i<=n;i++)
scanf("%d",&val[i]);
pre();
build(,,n);
scanf("%d",&Q);
while(Q--)
{
scanf("%s%d%d",st,&u,&v);
if(st[]=='M')
printf("%d\n",pathmax(u,v));
if(st[]=='S')
printf("%d\n",pathsum(u,v));
if(st[]=='H')
modify(,,n,pos[u],v);
}
return ;
}

算法复习——树链剖分模板(bzoj1036)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 树链剖分学习&BZOJ1036

    题目传送门 树链剖分,计算机术语,指一种对树进行划分的算法,它先通过轻重边剖分将树分为多条链,保证每个点属于且只属于一条链,然后再通过数据结构(树状数组.SBT.SPLAY.线段树等)来维护每一条链. ...

  8. spoj - Grass Planting(树链剖分模板题)

    Grass Planting 题意 给出一棵树,树有边权.每次给出节点 (u, v) ,有两种操作:1. 把 u 到 v 路径上所有边的权值加 1.2. 查询 u 到 v 的权值之和. 分析 如果这些 ...

  9. SPOJ QTREE - Query on a tree 【树链剖分模板】

    题目链接 引用到的大佬博客 代码来自:http://blog.csdn.net/jinglinxiao/article/details/72940746 具体算法讲解来自:http://blog.si ...

随机推荐

  1. C语言中的二级指针(双指针)

    原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7220688 C语言更多查看 C语言使用注意事项(一) C语言使用注意事项(二) ...

  2. CodeForces 149D Coloring Brackets (区间DP)

    题意: 给一个合法的括号序列,仅含()这两种.现在要为每对括号中的其中一个括号上色,有两种可选:蓝or红.要求不能有两个同颜色的括号相邻,问有多少种染色的方法? 思路: 这题的模拟成分比较多吧?两种颜 ...

  3. ubuntu 16.0 利用ant编译 hadoop-eclipse-plugins2.6.0

    折腾了两天,抱着不放弃的精神,我终于编译出我自己所需的hadoop中在eclipse中的插件 在网上下载的可能因为版本不一致,在编译的时候出现各种各样的问题,包括你的eclipse版本和hadoop版 ...

  4. 玄学C语言之scanf,printf

    #include <bits/stdc++.h> using namespace std; int main() { int a,c,d; ]; scanf("%d." ...

  5. MIPS简单入门

    What ‘s the MIPS? 汇编语言 汇编语言是一类语言的总称,因处理器不同,而对应的不同机器的指令集也不同,产生了很多种汇编语言. 目前最流行的是ARM,MIPS,x86.ARM用于大量的移 ...

  6. Webpack2 视频教程

      原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」.Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本 ...

  7. bxslider 使用帮助

    “bxSlider”就是一款响应式的幻灯片js插件 bxSlider特性 充分响应各种设备,适应各种屏幕: 支持多种滑动模式,水平.垂直以及淡入淡出效果: 支持图片.视频以及任意html内容: 支持触 ...

  8. java 操作mongodb查询条件的常用设置

    java操作mongodb进行查询,常用筛选条件的设置如下: 条件列表:BasicDBList condList = new BasicDBList(); 临时条件对象:BasicDBObject c ...

  9. Fortran学习笔记4(循环语句)

    Fortran学习笔记4 Fortran学习笔记4 逻辑运算 循环 Do语句 Do-While循环 循环控制 循环应用实例 逻辑运算 if命令需要和逻辑运算表达式搭配才能起到很好的效果.下面分别列出F ...

  10. 【dp 贪心】bzoj4391: [Usaco2015 dec]High Card Low Card

    巧妙的贪心 Description Bessie the cow is a huge fan of card games, which is quite surprising, given her l ...