题目传送门

树链剖分,计算机术语,指一种对树进行划分的算法,它先通过轻重边剖分将树分为多条链,保证每个点属于且只属于一条链,然后再通过数据结构(树状数组、SBT、SPLAY、线段树等)来维护每一条链。

以下是几种概念:

常见的路径剖分的方法是轻重树链剖分(启发式剖分)
将树中的边分为:轻边和重边 ž定义size(X)为以X为根的子树的节点个数。 ž令V为U的儿子节点中size值最大的节点,那么边(U,V)被称为重边,树中重边之外的边被称为轻边。
性质:ž轻边(U,V),size(V)<=size(U)/2。 ž从根到某一点的路径上,不超过O(logN)条轻边,不超过O(logN)条重路径。
树链剖分是先处理出树上一些链的关系,然后用线段树、树状数组之类。
树链剖分可以处理出一些重链轻链的关系。
查询时可以通过类似LCA的方式求出链上的信息。(在同一条链上可以直接查询)。
code:

/**************************************************************
Problem: 1036
User: yekehe
Language: C++
Result: Accepted
Time:2460 ms
Memory:4964 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int read()
{
char c;while(c=getchar(),(c<''||c>'')&&c!='-');
int x=,y=;c=='-'?y=-:x=c-'';
while(c=getchar(),c>=''&&c<='')x=x*+c-'';
return x*y;
} const int MAXN=; int N,Q,w[MAXN]; int head[MAXN],nxt[MAXN<<],To[MAXN<<],cnt;
void add(int x,int y)
{
To[cnt]=y;
nxt[cnt]=head[x];
head[x]=cnt;
cnt++;
} int f[MAXN],son[MAXN],dep[MAXN],siz[MAXN];
int top[MAXN],id[MAXN]; void dfs(int now,int d,int fa)
{
f[now]=fa,dep[now]=d,siz[now]=;
for(int i=head[now];i!=-;i=nxt[i]){
if(To[i]==fa)continue;
dfs(To[i],d+,now);
siz[now]+=siz[To[i]];
if(siz[To[i]]>siz[son[now]])
son[now]=To[i];
}
return ;
}//处理出f,dep,siz(siz可以求对子树修改,即修改x~x+siz[x]-1) int cot=;
void build(int now,int tp)
{
id[now]=++cot,top[now]=tp;
if(son[now])build(son[now],tp);
for(int i=head[now];i!=-;i=nxt[i]){
if(To[i]!=son[now]&&To[i]!=f[now])
build(To[i],To[i]);
}
}//求id(编号),重链的顶端 struct seg{
int x,s;
}t[MAXN*];
void updata(int now,int l,int r,int x,int c)
{
if(x<l || x>r)return ;
if(l==r){t[now]=(seg){c,c};return ;}
int mid=l+r>>;
updata(now<<,l,mid,x,c);
updata(now<<|,mid+,r,x,c);
t[now].x=max(t[now<<].x,t[now<<|].x);
t[now].s=t[now<<].s+t[now<<|].s;
} int Qs(int now,int l,int r,int ql,int qr)
{
if(ql<=l&&qr>=r)return t[now].s;
int mid=l+r>>,ans=;
if(mid>=ql)ans+=Qs(now<<,l,mid,ql,qr);
if(mid<qr) ans+=Qs(now<<|,mid+,r,ql,qr);
return ans;
} int Qx(int now,int l,int r,int ql,int qr)
{
if(ql<=l&&qr>=r)return t[now].x;
int mid=l+r>>,ans=-2e9;
if(mid>=ql)ans=max(ans,Qx(now<<,l,mid,ql,qr));
if(mid<qr) ans=max(ans,Qx(now<<|,mid+,r,ql,qr));
return ans;
} int findx(int u,int v)
{
int ans=-2e9;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans=max(ans,Qx(,,cot,id[top[u]],id[u]));
u=f[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
ans=max(ans,Qx(,,cot,id[v],id[u]));
return ans;
}//类似LCA int finds(int u,int v)
{
int ans=;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans+=Qs(,,cot,id[top[u]],id[u]);
u=f[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
ans+=Qs(,,cot,id[v],id[u]);
return ans;
} char C[];
int main()
{
memset(head,-,sizeof head);
memset(nxt,-,sizeof nxt);
N=read();
register int i,j;
for(i=;i<N;i++){
int x=read(),y=read();
add(x,y),add(y,x);
}
for(i=;i<=N;i++)w[i]=read();
dfs(,,),build(,);
for(i=;i<=N;i++)
updata(,,cot,id[i],w[i]);
Q=read();
for(i=;i<=Q;i++){
scanf("%s",C);
int x=read(),y=read();
if(C[]=='C')updata(,,cot,id[x],y);
else{
if(C[]=='M')printf("%d\n",findx(x,y));
else printf("%d\n",finds(x,y));
}
}
return ;
}

树链剖分学习&BZOJ1036的更多相关文章

  1. 树链剖分学习笔记 By cellur925

    先%一发机房各路祖传树剖大师%%%. 近来总有人向我安利树剖求LCA,然鹅我还是最爱树上倍增.然鹅又发现近年一些题目(如天天爱跑步.运输计划等在树上进行操作的题目),我有把树转化为一条链求解的思路,但 ...

  2. 【块状树】【树链剖分】bzoj1036 [ZJOI2008]树的统计Count

    很早之前用树链剖分写过,但是代码太长太难写,省选现场就写错了. #include<cstdio> #include<algorithm> #include<cstring ...

  3. LightOJ 1348 (树链剖分 + 线段树(树状数组))

    题目 Link 分析 典型的树链剖分题, 树链剖分学习资料 Code #include <bits/stdc++.h> using namespace std; const int max ...

  4. 【SPOJ-QTREE】树链剖分

    树链剖分学习 https://blog.csdn.net/u013368721/article/details/39734871 https://www.cnblogs.com/George1994/ ...

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

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

  6. 【BZOJ1036】 树的统计Count (树链剖分)

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

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

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

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

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

  9. 【BZOJ1036】树的统计Count(树链剖分,LCT)

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

随机推荐

  1. idea更新maven依赖包

    IntelljIdea 自动载入Maven依赖的功能很好用,但有时候会碰到问题,导致pom文件修改却没有触发自动重新载入的动作,此时需要手动强制更新依赖. 如下: (1)右键单击项目: (2)在弹出菜 ...

  2. BZOJ 1051 受欢迎的牛 缩点

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1051 题目大意: 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数( ...

  3. Linux下utf-8 BOM 的检查和删除 (65279错误解决办法)

    Java代码在转换为UTF-8编码后,Eclipse编译运行没有问题,但是用Maven编译时,抛出非法字符65278错误. 原因在于,转换后文件头部带有BOM信息,而Maven不支持,删掉文件头的BO ...

  4. 【[HAOI2015]树上染色】

    这道题真是非常神仙 第一眼看到题面肯定能想到状态是\(dp[i][j]\)表示\(i\)这棵子树里染了\(j\)个黑点的最大值 最大值? 什么最大值,之后就会发现这个样子完全没有办法转移 所以我们考虑 ...

  5. [CQOI2006]凸多边形(半平面相交)

    嘟嘟嘟 本来我要写feng shui这道题的.然后网上都说什么半平面相交,于是我还得现学这个东西,就来刷这道模板题了. 所谓的半平面相交和高中数学的分数规划特别像.比如这道题,把每一条边看成一条有向直 ...

  6. 【jQuery】学习jQuery插件的使用与写法(表单验证插件-validation)

    最新最全的插件可以从jQuery官方网站的插件板块下载,网站地址为:http://plugins.jquery.com/ Validation优点:内置验证规则:自定义验证规则:简单强大的验证信息提示 ...

  7. echo图片延迟加载js

    插件描述:和 Lazy Load 一样,Echo.js 也是一个用于图像延迟加载 JavaScript.不同的是 Lazy Load 是基于 jQuery 的插件,而 Echo.js 不依赖于 jQu ...

  8. 分享一个ASP.NET的弹出层,比较好用!

    网上的一些弹出层的控件多了去了,我很久之前用了一个,效果还不错,但如果应用到ASP.NET的话,会出现“弹出层内的控件runat='server'失效”的情况,具体情况我也不太会描述,但就是那些onc ...

  9. Maven搭建Spring MVC时使用jstl无效

    1 Maven引入依赖jar包:jstl.jar和standard.jar <dependency> <groupId>javax.servlet</groupId> ...

  10. 字符型设备驱动程序-first-printf以及点亮LED灯(二)

    编译这几个函数之前要学一下:Linux 的几个操作命令. 学习地址:http://edu.51cto.com/lesson/id-101824.html 重要的命令 有4个 :分别是 1.lsmod, ...