模板题。。。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 30001
#define INF 1000000000
inline char Nc(){
static char buf[],*p1=buf,*p2=buf;
if(p1==p2){
p2=(p1=buf)+fread(buf,,,stdin);
if(p1==p2)return EOF;
}
return *p1++;
}
inline void Read(int& x){
char c=Nc(),b=;
for(;c<''||c>'';c=Nc())if(c=='-')b=-;
for(x=;c>=''&&c<='';x=x*+c-,c=Nc());x*=b;
}
inline void Read(char* s){
int i=;
char c=Nc();
while(c!=' ')s[i]=c,i++,c=Nc();
}
int Len;
char s[];
inline void Print(int x){
if(x<){
putchar('-');
x=-x;
}
if(!x){
putchar('');putchar('\n');
return;
}
for(Len=;x;x/=)s[++Len]=x%;
for(;Len;Len--)putchar(s[Len]+);
putchar('\n');
}
struct Edge{
int To,Next;
}e[N<<];
inline int _Max(int x,int y){
return x>y?x:y;
}
int h[N],i,j,k,Num,n,m,T,a[N],w[N],x,y,w2[N],Top[N],Size[N],Son[N],f[N],Sum[N<<],Max[N<<],Deep[N];
char S[];
inline void Add(int x,int y){
e[++Num].To=y;e[Num].Next=h[x];h[x]=Num;
}
void Dfs1(int x,int Fa){
f[x]=Fa;Size[x]=;Deep[x]=Deep[Fa]+;
for(int i=h[x];i;i=e[i].Next)
if(e[i].To!=Fa){
Dfs1(e[i].To,x);
Size[x]+=Size[e[i].To];
if(Size[e[i].To]>Size[Son[x]])Son[x]=e[i].To;
}
}
void Dfs2(int x,int Tmp){
w[x]=++m;w2[m]=x;Top[x]=Tmp;
if(Son[x])Dfs2(Son[x],Tmp);
for(int i=h[x];i;i=e[i].Next)
if(e[i].To!=f[x]&&e[i].To!=Son[x])Dfs2(e[i].To,e[i].To);
}
void Build(int Node,int l,int r){
if(l==r){
Sum[Node]=Max[Node]=a[w2[l]];
return;
}
int Mid=(l+r)>>;
Build(Node<<,l,Mid);
Build(Node<<|,Mid+,r);
Sum[Node]=Sum[Node<<]+Sum[Node<<|];
Max[Node]=_Max(Max[Node<<],Max[Node<<|]);
}
void Update(int Node,int l,int r,int x,int y){
if(l==r){
Sum[Node]=Max[Node]=y;
return;
}
int Mid=(l+r)>>;
if(x<=Mid)Update(Node<<,l,Mid,x,y);else Update(Node<<|,Mid+,r,x,y);
Sum[Node]=Sum[Node<<]+Sum[Node<<|];
Max[Node]=_Max(Max[Node<<],Max[Node<<|]);
}
int Querysum(int Node,int l,int r,int L,int R){
if(l>R||r<L)return ;
if(l>=L&&r<=R)return Sum[Node];
int Mid=(l+r)>>;
return Querysum(Node<<,l,Mid,L,R)+Querysum(Node<<|,Mid+,r,L,R);
}
int Querymax(int Node,int l,int r,int L,int R){
if(l>R||r<L)return -INF;
if(l>=L&&r<=R)return Max[Node];
int Mid=(l+r)>>;
return _Max(Querymax(Node<<,l,Mid,L,R),Querymax(Node<<|,Mid+,r,L,R));
}
int Querysum_tree(int u,int v){
int Ans=;
while(Top[u]!=Top[v])
if(Deep[Top[u]]<Deep[Top[v]]){
Ans+=Querysum(,,m,w[Top[v]],w[v]);
v=f[Top[v]];
}else{
Ans+=Querysum(,,m,w[Top[u]],w[u]);
u=f[Top[u]];
}
if(w[u]<w[v])Ans+=Querysum(,,m,w[u],w[v]);else Ans+=Querysum(,,m,w[v],w[u]);
return Ans;
}
int Querymax_tree(int u,int v){
int Ans=-INF;
while(Top[u]!=Top[v])
if(Deep[Top[u]]<Deep[Top[v]]){
Ans=_Max(Ans,Querymax(,,m,w[Top[v]],w[v]));
v=f[Top[v]];
}else{
Ans=_Max(Ans,Querymax(,,m,w[Top[u]],w[u]));
u=f[Top[u]];
}
if(w[u]<w[v])Ans=_Max(Ans,Querymax(,,m,w[u],w[v]));else Ans=_Max(Ans,Querymax(,,m,w[v],w[u]));
return Ans;
}
int main()
{
Read(n);
for(i=;i<n;i++){
Read(x);Read(y);
Add(x,y);
Add(y,x);
}
for(i=;i<=n;i++)Read(a[i]);
Dfs1(,);
Dfs2(,);
Build(,,m);
Read(T);
while(T--){
Read(S);Read(x);Read(y);
if(S[]=='C')Update(,,m,w[x],y);else
if(S[]=='S')Print(Querysum_tree(x,y));else Print(Querymax_tree(x,y));
}
return ;
}

bzoj1036

bzoj1036--树链剖分的更多相关文章

  1. 洛谷3384&bzoj1036树链剖分

    值得注意的是: 一个点的子树是存在一起的...也就是说我们修改子树的时候只用... /********************************************************* ...

  2. 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

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

  3. 【BZOJ1036】 树的统计Count (树链剖分)

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

  4. BZOJ1036 [ZJOI2008]树的统计Count 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1036 题意概括 一个树,每个节点有一个权值.3种操作. 1:修改某一个节点的权值. 2:询问某两个 ...

  5. [BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分

    树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设( ...

  6. 【BZOJ1036】树的统计Count(树链剖分,LCT)

    题意:一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: ...

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

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

  8. bzoj1036 [ZJOI2008]树的统计Count(树链剖分)

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

  9. 树链剖分学习&BZOJ1036

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

  10. bzoj1036 count 树链剖分或LCT

    这道题很久以前用树链剖分写的,最近在学LCT ,就用LCT再写了一遍,也有一些收获. 因为这道题点权可以是负数,所以在update时就要注意一下,因为平时我的0节点表示空,它的点权为0,这样可以处理点 ...

随机推荐

  1. 程序员必须要知道的Hadoop的一些事实

    程序员必须要知道的Hadoop的一些事实.现如今,Apache Hadoop已经无人不知无人不晓.当年雅虎搜索工程师Doug Cutting开发出这个用以创建分布式计算机环境的开源软...... 1: ...

  2. MementoPattern(备忘录模式)

    /** * 备忘录模式 * @author TMAC-J * 用于存储bean的状态 */ public class MementoPattern { public class Memento{ pr ...

  3. IteratorPattern(迭代子模式)

    /** * 迭代子模式 * @author TMAC-J * 聚合:某一类对象的集合 * 迭代:行为方式,用来处理聚合 * 是一种行为模式,用于将聚合本身和操作聚合的行为分离 * Java中的COLL ...

  4. PHP设计模式(二)工厂方法模式(Factory Method For PHP)

    简单工厂简述: 简单工厂模式实现了生产产品类的代码跟客户端代码分离,在工厂类中你可以添加需要生成长跑的逻辑代码(new 产品类),但是问题来了,优秀的代码是符合"开闭原则"如果你要 ...

  5. hadoop 2.4 遇到的问题

    不管出什么问题,首先查看日志. 在启动过hadoop的前提下,打开浏览器,输入http://localhost:50070 点击Utilities下的logs,选择hadoop-root-datano ...

  6. .NET Core dotnet 命令大全

    dotnet 命令大全,让你理解dotnet 命令. 本文将以一个实例串起 dotnet 所有命令,让你玩转dotnet 命令. 本篇文章编写环境为windows 10 ,dotnet 命令同样适用于 ...

  7. [httpserver]如何解析HTTP请求报文

    这个http server的实现源代码我放在了我的github上,有兴趣的话可以点击查看哦. 在上一篇文章中,讲述了如何编写一个最简单的server,但该程序只是接受到请求之后马上返回响应,实在不能更 ...

  8. SQL Server 索引和表体系结构(非聚集索引)

    非聚集索引 概述 对于非聚集索引,涉及的信息要比聚集索引更多一些,由于整个篇幅比较大涉及接下来的要写的“包含列的索引”,“索引碎片”等一些知识点,可能要结合起来阅读理解起来要更容易一些.非聚集索引和聚 ...

  9. 从零到有——我的OA如何成长

    早前发文说要分享,马上进入了财务系统的开发,拖到现在,见笑了. 我在月初离职了,所以到处跑,找工作,想想南京.苏州.无锡(去玩的).杭州(路过).上海.珠海.深圳.广州.觉得找工作也差不多尾声了,就留 ...

  10. 命令行查看Windows激活信息(win7、win8、win10...)

    使用:Win+ R 组合键,打开运行命令框,复制命令,粘贴后回车. slmgr.vbs -xpr 查询Windows是否永久激活slmgr.vbs -dlv 查询到Windows的激活信息,包括:激活 ...