树链剖分
看逆天算法,品百味OI#4
1.重链剖分
给出如下定义:
-
重子结点:一个点的子节点中子树最大的点
-
轻子节点:剩余的子节点
-
重边:该节点到重子节点的边
-
轻边:到轻子节点的边
-
重链:若干条首尾相接的重边
预处理由两个DFS实现
-
DFS1:记录节点的父节点、深度、子树大小、重子结点
-
DFS2:记录所在链的链顶,重边优先遍历时的DFS序、DFS序对应的节点编号
这样之后就可以把树上操作转化为区间操作(重链遍历下
查询时用到类似
板子:
P3178 [HAOI2015] 树上操作
「ZJOI 2008」树的统计
QTREE
用到了边权下放(
ST.query(dfn[x] + 1,dfn[y],1,n,1)
(
[SDOI2011]染色
合并区间时要特判衔接处是否能合成一个区间,而且正是因为如此,线段树
if(ql > mid) query(ql,qr,mid + 1,r,rs(id));
else if(qr <= mid) query(ql,qr,l,mid,ls(id));
else
{
ans = query(ql,qr,l,mid,ls(id)) + query(ql,qr,mid + 1,r,rs(id));
if(t[ls(id)].rc == t[rs(id)].lc) ans--;
return ans;
}
全是细节
货车运输
没错就是最大生成树那个
原本的码量也大了
运输计划
没错就是那个二分答案后check能否删掉超过答案的
学了树剖后有了全新大发现
-
沿用二分思路,用树剖求
,好像也没啥特别的还加了码量,就lca短了点,优化了常数 -
考虑到树剖的区间操作优势,我们可以直接通过修改那
条路径来得到答案(正片)
我们选取
如果我们删掉了
很好想,过
这样一来又有重要的一点:删掉不同的边,结果极可能变化
也很好想,删掉不同的
总结就是:
把
对于一条路径,剖分后可以把它拆成若干条链(重/轻链的一部分),设为
对于每一个小段,我们可以预处理出不过这一段的路径中最长的。从而在查询时方便一点
void init(int x,int y,int z)
{
int res = 0;
int fx = top[x],fy = top[y];
// cout << fx << " " << fy << endl;
while(fx != fy)
{
//cout << 114 << endl;;
if(dep[fx] >= dep[fy]) {res++,P[res].c = dfn[fx],P[res].d = dfn[x];x = fa[fx];}
else {res++,P[res].c = dfn[fy],P[res].d = dfn[y];y = fa[fy];}
fx = top[x];fy = top[y];
}
if(dfn[x] > dfn[y]) swap(x,y);
res++;P[res].c = dfn[x] + 1,P[res].d = dfn[y];
sort(P + 1,P + res + 1,cmp);
if(P[1].c > 1) ST.add(1,P[1].c - 1,1,n,1,z);
if(P[res].d < n) ST.add(P[res].d + 1,n,1,n,1,z);
for(int i = 1;i < res;i++)
{
// cout << P[i].d + 1 << " " << P[i + 1].c - 1 << endl;
ST.add(P[i].d + 1,P[i + 1].c - 1,1,n,1,z);
}
//return;
}
时间效率(从高到低):树剖+ 补集(极限330ms)> 树剖+二分(极限约500ms) > 二分 + 倍增法lca(极限1.12s)
树剖常数真小
遥远的国度
换根问题
-
查询节点就是当前根,查询整个树
-
查询节点不是当前根的祖先,直接查询以该节点为根的子树
-
查询节点是当前根的祖先,这时要按跳链法找到当前节点的儿子
,那么 (以该儿子为根的子树)不纳入查询范围,即查询
找儿子:
int look(int x)
{
if(dfn[x] >= dfn[root] || dfn[x] + siz[x] - 1 < dfn[root]) return 114;
int pos = root;
while(top[pos] != top[x])
{
if(fa[top[pos]] == x) return top[pos];
pos = fa[top[pos]];
}
return hson[x];
}
可以看到,树剖的魅力就是把树转成纯纯的区间,查询某一部分就是对某一区间进行操作,这样就可以用线段树来降复杂度,非常的有实力
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?