接着找树剖的题。。。传送门(点我)

题意:给你一棵无根树,有三种操作:查询树上2点路径的点权和/最大点权;更改某点的点权。

解题思路:树链剖分裸题,我采用了常数较小的zkw线段树维护剖下来的树(毕竟线段树常数太大很危险),然后就是树剖的东西解决即可。

时间复杂度:期望:\( O(n \log \log^{2} n) \) 最坏:\( O(n \log^{2} n) \)

AC代码:(1452ms,3144KB on BZOJ)

#include <stdio.h>
#define inf 0x7fffffff
#define MN 30005
#define Mn 32768
#define v (edge[i].to)
inline int in(){
int x=,f=; char ch=getchar();
while(ch<''||ch>'') f=ch=='-'?-:,ch=getchar();
while(ch>=''&&ch<='') x=(x<<)+(x<<)+ch-'',ch=getchar();
return x*f;
}inline int max(int a,int b){return a>b?a:b;}
struct zxy{int to,nxt;}edge[MN<<];
int top[MN],sum[Mn<<],ma[Mn<<],siz[MN],dep[MN],son[MN],fa[MN],pos[MN],head[MN],cnt,dfsn,n,q,M;
inline void ins(int x,int y){edge[++cnt].to=y,edge[cnt].nxt=head[x],head[x]=cnt;}
inline void dfs1(int u,int f,int d){
dep[u]=d,fa[u]=f,siz[u]=;
for (register int i=head[u]; i; i=edge[i].nxt)
if (v!=f){
dfs1(v,u,d+);siz[u]+=siz[v];
if (siz[v]>siz[son[u]]) son[u]=v;
}
}
inline void dfs2(int u,int tp){
pos[u]=(++dfsn);top[u]=tp;if (son[u]) dfs2(son[u],tp);
for (register int i=head[u]; i; i=edge[i].nxt)
if (v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
inline void combine(int x){sum[x]=sum[x<<]+sum[x<<|];ma[x]=max(ma[x<<],ma[x<<|]);}
inline void A(int x,int k){sum[x+=M]=k,ma[x]=k;for (x>>=; x; x>>=) combine(x);}
inline int QM(int l,int r){
register int res=-inf;
for (l+=M-,r+=M+; l^r^; l>>=,r>>=){
if (~l&) res=max(res,ma[l^]);
if (r&) res=max(res,ma[r^]);
}return res;
}
inline int QS(int l,int r){
register int res=;
for (l+=M-,r+=M+; l^r^; l>>=,r>>=){
if (~l&) res+=sum[l^];
if (r&) res+=sum[r^];
}return res;
}
inline int queryS(int x,int y){
register int res=;
while(top[x]!=top[y])
if (dep[top[x]]>dep[top[y]]) res+=QS(pos[top[x]],pos[x]),x=fa[top[x]];
else res+=QS(pos[top[y]],pos[y]),y=fa[top[y]];
if (dep[x]<dep[y]) res+=QS(pos[x],pos[y]);
else res+=QS(pos[y],pos[x]);return res;
}
inline int queryM(int x,int y){
register int res=-inf;
while(top[x]!=top[y])
if (dep[top[x]]>dep[top[y]]) res=max(res,QM(pos[top[x]],pos[x])),x=fa[top[x]];
else res=max(res,QM(pos[top[y]],pos[y])),y=fa[top[y]];
if (dep[x]<dep[y]) res=max(res,QM(pos[x],pos[y]));
else res=max(res,QM(pos[y],pos[x]));return res;
return res;
}
void init(){
n=in();for (int i=; i<n; ++i){
register int x=in(),y=in();
ins(x,y);ins(y,x);
}
dfs1(,,);dfs2(,);for (M=; M<n+; M<<=);
for (register int i=; i<=n; ++i)sum[M+pos[i]]=ma[M+pos[i]]=in();
for (register int i=M; i; --i) combine(i);
}
void solve(){
q=in();while(q--){
register char op[];scanf("%s",op);register int x=in();
if (op[]=='C') A(pos[x],in());
else{
if (op[]=='M') printf("%d\n",queryM(x,in()));
else printf("%d\n",queryS(x,in()));
}
}
}
int main(){init();solve();return ;}

【BZOJ1036】【ZJOI2008】数的统计的更多相关文章

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

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

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

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

  3. bzoj1036 [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 12646  Solved: 5085 [Subm ...

  4. bzoj千题计划124:bzoj1036: [ZJOI2008]树的统计Count

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分板子题 #include<cstdio> #include<iost ...

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

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

  6. 【lct】bzoj1036 [ZJOI2008]树的统计Count

    题意:给你一棵树,点带权,支持三种操作:单点修改:询问链上和:询问链上max. 这里的Query操作用了与上一题不太一样的做法(上一题用那种做法,因为在边带权的情况下换根太困难啦): 先ChangeR ...

  7. BZOJ1036[ZJOI2008]树的统计Count 题解

    题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.有一些操作:1.把结点u的权值改为t:2.询问从点u到点v的路径上的节点的最大权值 3.询问从点u到点v的路径上的节点的权值和 ...

  8. bzoj1036: [ZJOI2008]树的统计Count 树链剖分+线段树

    入门题 + 熟悉代码 /************************************************************** Problem: 1036 User: 96655 ...

  9. bzoj1036 zjoi2008 树的统计 count

    填坑= =第一道裸树剖 #include<cstdio> #include<algorithm> #include<cstring> #include<cst ...

  10. bzoj1036 [ZJOI2008]树的统计

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

随机推荐

  1. VS系列控制台闪退解决

    查阅--->总结-->实践--> 按红色标识走 ,完美解决! 至此,完美解决:原理不深究:

  2. Codeforces 837E. Vasya's Function

    http://codeforces.com/problemset/problem/837/E   题意: f(a, 0) = 0; f(a, b) = 1 + f(a, b - gcd(a, b)) ...

  3. 【编程开发】PHP---面向对象

    面向对象编程 类:在现实世界中,任何事物都有种类的概念:车 类是由特征和行为构成的. 特征:都是不动的,从出厂的时候就已经内置好了(属性) 行为:一种动的状态.(方法(函数)) 行为依赖于这些特征,而 ...

  4. 利用Node的chokidar 监听文件改变的文件。

    最近维护一个项目.每次改完东西,都要上传到服务器.然后有时候就忘记一些东西,于是就想有没有可以方法能监听文件的改变.然后我再利用程序把更改的文件一键上传到服务器. 于是就找到了nodejs 的chok ...

  5. JAVA_SE基础——18.方法的递归

    方法的递归是指在一个方法的内部调用自身的过程,递归必须要有结束条件,不然就会陷入无限递归的状态,永远无法结束调用,接下来用一个最简单的例子来体现下方法递归,使用递归算法计算自然数之和: public ...

  6. VMware网络配置

    NAT模式 首先保证虚拟机网卡和主机对接,虚拟机网络连接要和主机在同一网段 1. 控制面板\网络和 Internet\网络连接中配置VMnet8 2. 编辑虚拟机网络配置 此处子网ip需要和Vnet8 ...

  7. 请求方式:request和 get、post、put

    angular 的 http 多了 Request, Headers, Response ,这些都是游览器的"新特性" Fetch API. Fetch API 和以前的 xmlh ...

  8. Docker学习笔记 - Docker的守护进程

    学习目标:  查看Docker守护进程的运行状态 启动.停止.重启Docker守护进程 Docker守护进程的启动选项 修改和查看Docker守护进程的启动选项 1.# 查看docker运行状态  方 ...

  9. SpringCloud的EurekaClient : 客户端应用访问注册的微服务(有断路器场景)

    演示客户端应用如何访问注册在EurekaServer里的微服务 一.概念和定义 采用Ribbon或Feign方式访问注册到EurekaServer中的微服务.1.Ribbon实现了客户端负载均衡,2. ...

  10. C#实现导出Excel

    这段时间用到了导出Excel的功能,这个功能还是比较常用的,我常用的有两个方法,现在整理一下,方便以后查看. 一.实现DataTable数据导出到本地,需要自己传进去导出的路径. /// <su ...