【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 ...
随机推荐
- python 代码中log表示含义
log表示以e为底数的对数函数符号.其验证代码如下: a=np.log(np.e )print(a)print(np.e)
- 79.mobile/js---手机端分享调用功能的实现(只能在真机上测试有效)
html:<a href="javascript:void(0);" class="all-share" onclick="call('defa ...
- JavaWeb 之 Filter 验证用户登录案例
需求: 1. 访问一个网站的资源.验证其是否登录 2. 如果登录了,则直接放行. 3. 如果没有登录,则跳转到登录页面,提示"您尚未登录,请先登录". 代码实现: import j ...
- ABAP和Java里的单例模式攻击
面向对象编程世界里的单例模式(Singleton)可能是设计模式里最简单的一种,大多数开发人员都觉得可以很容易掌握它的用法.单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点. 然而在某些场 ...
- 二维码扫码登录原理及简单demo
扫码登录原理转载自: https://www.cnblogs.com/liyasong/p/saoma.html 需求介绍 首先,介绍下什么是扫码登录.现在,大部分同学手机上都装有qq和淘宝,天猫等这 ...
- idea2019的安装与激活
1.安装及相关资料下载 链接:https://pan.baidu.com/s/1njKjorAvaWftuGCvCQzP3A 提取码:r8h8 2.安装步骤 几乎是傻瓜式的安装,点击下一步即可 注意两 ...
- docker容器监控:cadvisor+influxdb+grafana
cadvisor+influxdb+grafana可以实现容器信息获取.存储.显示等容器监控功能,是目前流行的docker监控开源方案. 方案介绍 cadvisor Google开源的用于监控基础设施 ...
- 用session防止网站页面被频繁刷新
session防止网站页面频繁被刷新 <?php //公司网站老是受到攻击,这是之前在网上看到的一个用session防止IP频繁访问的方法,我们公司用的是Memcache,都差不多,就是存储方式 ...
- 视图查询的数据和sql查询的数据不一样
视图查询的数据和sql查询的数据不一样. 手动刷新视图 exec sp_refreshview 视图名称
- linux的后台运行相关命令
screen -S name 创建一个名为name的后台,或者说bash面板,在这上面运行的任务不会因为连接断开而退出,且保留bash上的信息 screen -ls 列出所有的screen scree ...