题目

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

分析

树链剖分

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
using namespace std;
#define MN 30000
#define fINF -30000000
int fa[MN+],W[MN+],ans[MN+],dfn[MN+],sons[MN+],fl[MN+],head[MN+],ccnt=,cnt=;
struct data{int to,next;}e[MN*+];
void ins(int u,int v){
e[++ccnt].to=v;e[ccnt].next=head[u];head[u]=ccnt;
e[++ccnt].to=u;e[ccnt].next=head[v];head[v]=ccnt;
}
struct TREE{int val,max;}t[MN*+];
int n,q;
void update(int k,int l,int r,int q,int v){
if(l==r) {t[k].val=t[k].max=v;return;}
int mid=(l+r)/;
if(q<=mid) update(k<<,l,mid,q,v);
if(q>mid) update(k<<|,mid+,r,q,v);
t[k].val=t[k<<].val+t[k<<|].val;
t[k].max=max(t[k<<].max,t[k<<|].max);
}
void dfs1(int x){
sons[x]=;
for(int i=head[x];i;i=e[i].next){
if(e[i].to==fa[x]) continue;
fl[e[i].to]=fl[x]+; fa[e[i].to]=x;
dfs1(e[i].to);
sons[x]+=sons[e[i].to];
}
}
void dfs2(int x,int chain){
int k=;
dfn[x]=++cnt;
ans[x]=chain;
for(int i=head[x];i;i=e[i].next)
if(fl[e[i].to]>fl[x]&&sons[e[i].to]>sons[k]) k=e[i].to;
if(k==) return;
dfs2(k,chain);
for(int i=head[x];i;i=e[i].next)
if(fl[e[i].to]>fl[x]&&k!=e[i].to)
dfs2(e[i].to,e[i].to);
}
int query_max(int k,int l,int r,int a,int b){
if(a<=l&&r<=b) return t[k].max;
int m=(l+r)/,anss=fINF;
if(a<=m) anss=max(anss,query_max(k<<,l,m,a,b));
if(m<b) anss=max(anss,query_max(k<<|,m+,r,a,b));
return anss;
}
int query_sum(int k,int l,int r,int a,int b){
if(a<=l&&r<=b) return t[k].val;
int m=(l+r)/,anss=;
if(a<=m) anss+=query_sum(k<<,l,m,a,b);
if(m<b) anss+=query_sum(k<<|,m+,r,a,b);
return anss;
}
int find_sum(int x,int y){
int sum=;
while(ans[x]!=ans[y]){
if(fl[ans[x]]<fl[ans[y]]) swap(x,y);
sum+=query_sum(,,n,dfn[ans[x]],dfn[x]);
x=fa[ans[x]];
}
if(dfn[x]>dfn[y]) swap(x,y);
sum+=query_sum(,,n,dfn[x],dfn[y]);
return sum;
}
int find_max(int x,int y){
int mx=fINF;
while(ans[x]!=ans[y]){
if(fl[ans[x]]<fl[ans[y]]) swap(x,y);
mx=max(mx,query_max(,,n,dfn[ans[x]],dfn[x]));
x=fa[ans[x]];
}
if(dfn[x]>dfn[y]) swap(x,y);
mx=max(mx,query_max(,,n,dfn[x],dfn[y]));
return mx;
}
void solve(int k,int a,int b){
if(k==) printf("%d\n",find_max(a,b));
if(k==) printf("%d\n",find_sum(a,b));
if(k==) update(,,n,dfn[a],b);
}
int main(){
int u,v,ro;
scanf("%d",&n);
for(int i=;i<n;i++) scanf("%d%d",&u,&v),ins(u,v);
dfs1(); dfs2(,);
for(int i=;i<=n;i++) scanf("%d",&W[i]),update(,,n,dfn[i],W[i]);
scanf("%d",&q);
while(q--){
char ch=getchar(); int k;
int x1=,f1=,x2=,f2=;
while(ch<''||ch>''){
if(ch=='X') k=; if(ch=='U') k=;
if(ch=='H') k=; if(ch=='-') f1=-;
ch=getchar();
}
while(ch>=''&&ch<='') x1=x1*+ch-'',ch=getchar();
while(ch<''||ch>'') f2=ch=='-'?-:,ch=getchar();
while(ch>=''&&ch<='') x2=x2*+ch-'',ch=getchar();
solve(k,x1*f1,x2*f2);
}
return ;
}

————————————————————————————————————

来自PaperCloud的博客,未经允许,请勿转载,谢谢。

【BZOJ 1036】 树的统计count的更多相关文章

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

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

  2. [置顶] bzoj 1036 树的统计Count 点权值模板

    树链剖分 点权型可做模板,链路剖分的思想把点hash到线段树的上,然后可通过n*(log(n)*log(n))的复杂度在树上操作,在线段树上能操作的在链路上都能操作. #include<cstd ...

  3. bzoj 1036 树的统计Count

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

  4. BZOJ - 1036 树的统计Count (LCT)

    LCT试炼题(代码量居然完爆树剖?) #include<bits/stdc++.h> using namespace std; ,inf=0x3f3f3f3f; ],flp[N],n,m, ...

  5. BZOJ - 1036 树的统计Count (树链剖分+线段树)

    题目链接 #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f; ],mx[ ...

  6. BZOJ 1036 树的统计-树链剖分

    [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...

  7. Codevs 2460 == BZOJ 1036 树的统计

     2460 树的统计 2008年省队选拔赛浙江 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 一棵树上有n个节点,编号分别为1 ...

  8. BZOJ 1036 树的统计

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

  9. HYSBZ 1036 树的统计Count(树链剖分)题解

    思路: 树链剖分,不知道说什么...我连模板都不会用 代码: #include<map> #include<ctime> #include<cmath> #incl ...

  10. BZOJ 1036 树的统计(树链剖分)

    点权树链剖分模板题. # include <cstdio> # include <cstring> # include <cstdlib> # include &l ...

随机推荐

  1. [golang]svg图片默认按照左上角旋转,改为按中心旋转,重新计算中心偏移量

    1 前言 svg图片默认按照左上角旋转,改为按中心旋转,重新计算中心偏移量 2 代码 type Point struct { X float64 Y float64 } func GetOffsetX ...

  2. Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器

    Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器 一丶关键字:global,nonlocal global 声明全局变量: ​ 1. 可以在局部作用域声明一 ...

  3. 又一个秘密如何让浏览器访问最新的js,css等外部引用

    在引用文件末尾加上一个参数,让浏览器知道这个文件跟上一个文件是不同的,让浏览器去服务器重新加载最新的,例如:<script type="text/javascript" sr ...

  4. Java 之 ServletContext 对象

    ServletContext 对象 一.概念 ServletContext对象:代表整个 web 应用,可以和程序的容器(服务器)来通信. 二.获取 1.通过request 获取 方法: reques ...

  5. 大数据系列文章-Hadoop基础介绍(一)

    Hadoop项目背景简介 2003-2004年,Google公开了部分GFS个Mapreduce思想的细节,以此为基础Doug Cutting等人用了2年的业余时间,实现了DFS和Mapreduce机 ...

  6. Apache 正向代理与反向代理配置

    Apache提供了 mod_proxy 模块用于提供代理服务,能够支持的包括正向代理.反向代理.透明代理.缓存.负载均衡,HTTP代理.FTP代理.SSL代理等若干强大的功能. 配置代理方法很简单那, ...

  7. Docker镜像管理基础篇

    Docker镜像管理基础篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Docker Images Docker镜像还有启动容器所需要的文件系统及其内容,因此,其用于创建并启 ...

  8. Python入门篇-StringIO和BytesIO

    Python入门篇-StringIO和BytesIO 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.StringIO(用于文本处理) 1>.使用案例 #!/usr/bin ...

  9. Environment类在代码中的使用

    string environmentVariable = Environment.GetEnvironmentVariable("TrustMerchantIniFile"); 可 ...

  10. jquery选择器之全选择器

    在CSS中,经常会在第一行写下这样一段样式 * {padding: 0; margin: 0;} 通配符*意味着给所有的元素设置默认的边距.jQuery中我们也可以通过传递*选择器来选中文档页面中的元 ...