写点基础的东西。随便写的,勿喷。

top cluster

一个 cluster 是一个联通子图,且至多有两个点与其他部分连接

这两个点被称为 boundary node 其余点被称为 internal node,两个 boundary node 间的路径被称为 cluster path

而我们的树分块就是将原树分为 \(\sqrt n\) 个 cluster

将 boundary node 看成点,cluster 看成边,则构造出原图的收缩树

性质:不同的 cluster 最多共用两个 boundary node 而边集不交

构造方法

选取任意节点作为根,并强制根作为一个 boundary node

从根开始往下 dfs 并存储未归类进 cluster 的边(实际上存的是点,代表的是其连向其父亲的边)

当某个点 \(u\) 结束 dfs 假若发生以下三种情况之一则将其标记为 boundary node

  1. \(u\) 未根节点

  2. \(u\) 有至少两个子树中存在 boundary

  3. 栈中剩余边数量大于 \(B\)

好,假若点 \(u\) 成为了 boundary node 接下考虑如何把其子树划进不同的 cluster

我们贪心的在栈中选择极长前缀直至以下情况发生

  1. 子树用完

  2. 新加入一个子树会使当前 cluster 中 boundary 数量超过 \(2\)

  3. 新加入一个子树会使当前 cluster 大小超过 \(B\)

dfs 全部结束我们即可获得一种合法方案

根据论文里的结论,这样的划分 cluster 大小不超过 \(B\) 且数量不超过 \(6 \times \frac{n}{B}\)

贴一个板子题 P2420 (查询两点异或和)的代码,已经 AC

#include<bits/stdc++.h>
//#define int long long
//#define lowbit(x) (x&-(x))
using namespace std;
const int maxn = 1e5+114;
const int B = 318;
int fa[maxn];//原树上的父亲
int sz[maxn];//簇的大小
int tot;
int up[maxn],down[maxn];//所在的簇的上下界点
int dep[maxn];//深度
int st[maxn],top;//存贮还未分配的边
vector<int> edge[maxn];
int st_top[maxn];
int wait[maxn];//待分配的边
int low[maxn];//最浅界点
int CL[maxn],CLtot;
int CL_fa[maxn],CL_near[maxn],CL_up[maxn],CL_down[maxn];//在收缩树上的父亲 距离最近的簇路径上节点 所属簇的上下界点 (若为界点,则其所属簇为其作为下界点时所属的簇)
vector<int> cluster;//储存所有界点
vector<int> Down[maxn];//整个簇中出了上界点的点存入下界点中
int Point[maxn];//点权
int w[maxn];//一个簇上的上界点到根的路径上点权异或和
void work(int x){
for(int r=x;r!=0;r=fa[r]) w[x]^=Point[x];
}
void add_CL(int u,int v){//新建一个簇
if(!v) v=CL[CLtot];
CL_fa[v]=u,CL_near[u]=u;
for(int r=v;r!=u;r=fa[r])
CL_near[r]=r,w[v]^=Point[r];
for(int i=1;i<=CLtot;i++){
int r=CL[i],j;
CL_up[r]=u,CL_down[r]=v,Down[v].push_back(r);
for (j=r;!CL_near[j];j=fa[j]);
CL_near[r]=CL_near[j];
}
CLtot=0;
}
map<int,int> val[maxn];
void build(int u,int father){
dep[u]=dep[father]+1;
Point[u]=val[u][father];
fa[u]=father;
st_top[u]=top;
for(auto it=edge[u].begin();it!=edge[u].end();it++)
if((*it)==father){
edge[u].erase(it);
break;
}
wait[u]=true;
int cnt=0;
for(int v:edge[u]){
st[++top]=v;
build(v,u);
wait[u]+=wait[v];
low[v]&&(low[u]=low[v],cnt++);
}
if(wait[u]>B||cnt>1||father==0){
wait[u]=0,low[u]=u,cluster.push_back(u);
for(int i=0,j=st_top[u]+1,Cnt=0,cur_down=0,v;i<=edge[u].size();i++){
// Cnt 簇的大小 cur_down 簇的下界点
v=(i==edge[u].size())?0:edge[u][i];
if(Cnt+wait[v]>B||(cur_down&&low[v])||!v){ //已无法往当前簇中再加入一个子树
for (;(j<st_top[v]||!v)&&j<=top;j++)
CL[++CLtot]=st[j];
add_CL(u,cur_down),Cnt=cur_down=0;
}
Cnt+=wait[v],low[v]&&(cur_down=low[v]);
}
}
}
int n,q,rt;
int ask(int u){
int res=0;
while(u!=CL_up[u]) res^=Point[u],u=fa[u];
res^=w[u];
return res;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<n;i++){
int u,v,w;
cin>>u>>v>>w;
val[u][v]=val[v][u]=w;
edge[u].push_back(v);
edge[v].push_back(u);
}
build(1,0);
for(int x:cluster) work(x);
cin>>q;
for(int i=1;i<=q;i++){
int u,v;
cin>>u>>v;
cout<<(ask(u)^ask(v))<<'\n';
}
return 0;
}

接下来讲点运用:

路径分解:

我们将点 \(u \to rt\) 的路径分为三段。

\(u \to v\) 其中 \(v\) 是 \(u\) 往上走遇到的第一个在 cluster path 上的节点

\(v \to w\) 其中 \(w\) 是 \(v\) 往上走遇到的第一个 up boundary node

\(w \to rt\) 其中 \(rt\) 是根节点

根据 top cluster 的性质,第一条和第二条路径长度不大于 \(B\)

而第三条路径可以在收缩树上解决,收缩树的大小为 \(O(\frac{n}{B})\)

而在这些地方维护前缀和或者差分就可以做到查询修改一者 \(O(\sqrt n)\) 另一者 \(O(1)\)。

Top cluster 树分块的更多相关文章

  1. 【BZOJ 3735】苹果树 树上莫队(树分块+离线莫队+鬼畜的压行)

    2016-05-09 UPD:学习了新的DFS序列分块,然后发现这个东西是战术核导弹?反正比下面的树分块不知道要快到哪里去了 #include<cmath> #include<cst ...

  2. [BZOJ 1086] [SCOI2005] 王室联邦 【树分块】

    题目链接:BZOJ - 1086 题目分析 这道题要求给树分块,使得每一块的大小在 [B, 3B] 之间,并且可以通过一个块外的节点(块根)使得整个块联通. 那么我们使用一种 DFS,维护一个栈,DF ...

  3. hdu 4366 Successor - CDQ分治 - 线段树 - 树分块

    Sean owns a company and he is the BOSS.The other Staff has one Superior.every staff has a loyalty an ...

  4. 【BZOJ】4129: Haruna’s Breakfast 树分块+带修改莫队算法

    [题意]给定n个节点的树,每个节点有一个数字ai,m次操作:修改一个节点的数字,或询问一条树链的数字集合的mex值.n,m<=5*10^4,0<=ai<=10^9. [算法]树分块+ ...

  5. 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法

    [题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的 ...

  6. 【bzoj1086】[SCOI2005]王室联邦 树分块

    题目描述 将一棵n个点的树分为若干“块”,每个块满足:大小在B到3B之间,并且这个“块”添加某个点后连通.求方案. 输入 第一行包含两个数N,B(1<=N<=1000, 1 <= B ...

  7. 种树 by yoyoball [树分块+bitset]

    题面 给定一棵树,有点权 每次询问给出一些点对,求这些点对之间的路径的并集上不同权值的个数,以及这些权值的$mex$ 思路 先考虑只有一对点对,只询问不同权值个数的问题:树上莫队模板题 然后加个$me ...

  8. BZOJ1086 王室联邦 —— 树分块

    题目链接:https://vjudge.net/problem/HYSBZ-1086 1086: [SCOI2005]王室联邦 Time Limit: 10 Sec  Memory Limit: 16 ...

  9. 洛谷.2590.[ZJOI2008]树的统计(树分块)

    题目链接 Update:这种分块写法...可以被卡掉啊... 好像没有靠谱的树分块写法... /* 对树上节点进行分块,每个点记录dep,fa,val,Max,Sum,Max,Sum表示当前点在该块内 ...

  10. BZOJ.3720.Gty的妹子树(树分块)

    题目链接 洛谷上惨遭爆零是为什么.. 另外这个树分块算法是假的. /* 插入删除只涉及一个数,故每次可以枚举一遍,而不是重构完后sort */ #include<cmath> #inclu ...

随机推荐

  1. Oracle中ALTER TABLE的五种用法(四、五)

    首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1 ...

  2. nodejs搭建chatgpt服务

    5分钟快速搭建基于nodejs的chatgpt服务 写在前面 首先大家都知道,在国内是无法成功调用openapi的接口,甚至openai的官网都很难打开.所以如果想使用chatgpt的几乎是不可能,不 ...

  3. RemoteView 替代品和类似软件

    RemoteView 是一款远程控制软件,使您可以通过Internet连接远程访问计算机和移动设备,而不受时间和地点的限制. 您可以快速,安全地实时轻松地控制计算机和移动设备. 您可以使用我们的iOS ...

  4. 万事通,专精部分领域的多功能 Transformer 智能体

    介绍 我们很高兴分享"万事通"(Jack of All Trades,简称 JAT) 项目,该项目旨在朝着通用智能体的方向发展.该项目最初是作为对 Gato (Reed 等,202 ...

  5. 80x86汇编—80x86架构

    文章目录 计算机如何工作 存储器 逻辑地址到物理地址 寄存器 数据寄存器使用细节 其他知识点细节 堆栈Stack 标志寄存器 中断 汇编入门简单,深入难 使用8086架构进行学习,本章节如果没有学过计 ...

  6. C# 调用 qrencode的动态库

    自己根据qrencode的源码导了一个dll动态库,见: https://www.cnblogs.com/HelloQLQ/p/16364825.html 自己希望能用C#语言调用以下. 首先构建需要 ...

  7. Swoole 源码分析之 Timer 定时器模块

    原文首发链接:Swoole 源码分析之 Timer 定时器模块 大家好,我是码农先森. 引言 Swoole 中的毫秒精度的定时器.底层基于 epoll_wait 和 setitimer 实现,数据结构 ...

  8. QuickApp 快应用中 或 nodejs 中 API接品调用时 GBK转UTF8

    请求接口地址:https://doc.quickapp.cn/features/system/fetch.html?h=fetch 第一步,安装包: npm install iconv-lite as ...

  9. 在Windows上运行Rainbond,10分钟快速安装

    前言 Windows 桌面运行 Rainbond,Windows 开发者的新选择. 经过适配Mac以后,Windows的适配也是成为了近期的小目标,经过不断地测试,不断地研究.最后也是达成了完美运行的 ...

  10. ceph deploy部署ceph集群 ceph扩容 rbd存储

    架构拓扑 节点主机 节点IP 节点角色 OS ceph-admin 10.0.0.60 admin deploy mds centos7 ceph-node1 10.0.0.61 mon osd md ...