【BZOJ 1036】 树的统计count
题目
一棵树上有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的更多相关文章
- BZOJ 1036 树的统计Count 树链剖分模板题
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1036 题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将 ...
- [置顶] bzoj 1036 树的统计Count 点权值模板
树链剖分 点权型可做模板,链路剖分的思想把点hash到线段树的上,然后可通过n*(log(n)*log(n))的复杂度在树上操作,在线段树上能操作的在链路上都能操作. #include<cstd ...
- bzoj 1036 树的统计Count
题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- BZOJ - 1036 树的统计Count (LCT)
LCT试炼题(代码量居然完爆树剖?) #include<bits/stdc++.h> using namespace std; ,inf=0x3f3f3f3f; ],flp[N],n,m, ...
- BZOJ - 1036 树的统计Count (树链剖分+线段树)
题目链接 #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f; ],mx[ ...
- BZOJ 1036 树的统计-树链剖分
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...
- Codevs 2460 == BZOJ 1036 树的统计
2460 树的统计 2008年省队选拔赛浙江 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 一棵树上有n个节点,编号分别为1 ...
- BZOJ 1036 树的统计
Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...
- HYSBZ 1036 树的统计Count(树链剖分)题解
思路: 树链剖分,不知道说什么...我连模板都不会用 代码: #include<map> #include<ctime> #include<cmath> #incl ...
- BZOJ 1036 树的统计(树链剖分)
点权树链剖分模板题. # include <cstdio> # include <cstring> # include <cstdlib> # include &l ...
随机推荐
- Go defer 会有性能损耗,尽量不要用?
上个月在 @polaris @轩脉刃 的全栈技术群里看到一个小伙伴问 “说 defer 在栈退出时执行,会有性能损耗,尽量不要用,这个怎么解?”. 恰好前段时间写了一篇 <深入理解 Go def ...
- 2019 网易java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.网易等公司offer,岗位是Java后端开发,因为发展原因最终选择去了网易,入职一年时间了,也成为了面试官,之 ...
- 小div在大div中垂直居中方式
代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- SPI bus 的收发编程
https://linux-sunxi.org/SPIdev The SPI bus (or Serial Peripheral Interface bus) is a synchronous ser ...
- storm整合kafka storm-kafka-client
pom.xml-注意jar-log4j---------------------<dependencies> <dependency> <groupId>org.a ...
- InnoDB存储引擎与MyIsam存储引擎的区别
特性比较 mysql5.5之后默认的存储引擎为InnoDB,在此之前默认存储引擎是MyIsam 特点 MyIsam InnoDB 锁机制 表锁 行锁 事务 不支持 支持 外键 不支持 支持 B树索引 ...
- 将mysql从MyISAM更改为INNODB
今天更新django中的表字段,由于mysql从5.1升级到5.7.以前的外键关联必须从MYISAM改新为INNODB才可以继续. 过程有点刺激,但还好,只要想清楚了过程,提前作好备份,就没啥大问题. ...
- WM_MOUSEWHEEL、WM_LBUTTONDOWN等父子窗口消息传递陷阱
mfc中,碰到以下问题:父对话框A.子窗口B.B是CWnd对象.需要在B中处理WM_MOUSEWHEEL.WM_LBUTTONDOWN等消息. 所以在B中增加对应的消息处理,发现B中的消息循环中,收不 ...
- python list 字符串排序
#coding:utf-8 import re s = ['dat2','dat10','dat5'] #方法一 new = sorted(s,key = lambda i:int(re.search ...
- Echo团队Alpha冲刺 - 总结随笔
班级:软件工程1916|W 作业:项目Alpha冲刺(团队) 团队名称:Echo 作业目标:完成项目Alpha冲刺 评审表:腾讯文档 Alpha冲刺随笔集合 目录 团队博客汇总 项目预期计划及完成情况 ...