题目

一棵树上有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. 【面试突击】-缓存击穿(布隆过滤器 Bloom Filter)

    原文地址:https://blog.csdn.net/fouy_yun/article/details/81075432 前面的文章介绍了缓存的分类和使用的场景.通常情况下,缓存是加速系统响应的一种途 ...

  2. python day 16: FTP脚本作业用例图,类图,活动图与代码重写

    目录 python day 16 1. FTP脚本的用例图 python day 16 2019/10/22 - 2019/10/26 学习资料来自老男孩教育 1. FTP脚本的用例图 老师的讲解视频 ...

  3. python day 14: 作业:开发一个能够多用户上传文件的FTP脚本

    目录 python day 14 1. 要求 2. 自己写的程序目录 3. models模块 4. settings模块 5. tcp_server模块 6. client模块 7. 后记 pytho ...

  4. Flask--配置文件

    配置文件 配置文件的方式有很多,下面介绍两种: 第一种:根据全局变量实现 App.py from flask import Flask, session app = Flask(__name__) # ...

  5. 17,Flask-admin后台管理系统总结

    导入包 from flask_admin import Admin,BaseView,expose,AdminIndexView from flask_admin.contrib.sqla impor ...

  6. ELK Stack部署

    部署ELK Stack 官网:https://www.elastic.co 环境准备: ip hostname 服务 用户.组 192.168.20.3 node2003 kibana6.5,file ...

  7. js eval()

    1.基本字符串(数组字符串,json字符串)类型转化为对象(对象数组,json对象):  eval("("+字符串+")"); 2.json字符串转化为json ...

  8. 一套不错的docker lnmp

    github地址:https://github.com/yeszao/dnmp 镜像基于linux alpine 内存占用小 安装常用软件采用apk命令

  9. Linux标准IO和管道

    Linux标准IO和管道 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.标准输入和输出 程序:指令+数据 读入数据:Input 输出数据:Output 打开的文件都有一个fd: ...

  10. waitpid()函数

    waitpid函数 作用同于wait,但可指定pid进程清理,可以不阻塞. pid_t waitpid(pid_t pid,int *status,int options);成功:返回清理掉的子进程I ...