点分树略记
前置知识是点分治。点分树就是动态点分治。
将点分治的递归过程建成树,每个分治中心(重心)向上一层分治中心连边,形成一棵树的结构。
树高是 \(O(\log n)\) 的,这意味着我们可以暴力向上跳分治中心。
子树大小之和是 \(O(n \log n)\) 的,这意味着我们可以给每个分治中心都开一个数据结构,用数据结构维护每一层的答案,还可以支持修改操作。
建树过程就是做一次点分治。
int divfa[maxn];
void divide(int u)
{
vis[u]=true;
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].v;
if(vis[v]) continue;
U=sz[v],rt=-1,getrt(v,u);
divfa[rt]=u,divide(rt);
}
}
每次询问暴力向上跳分治中心,计算以询问点为端点,跨过当前分治中心的答案。
先求出另一端点在当前分治中心管辖范围内的答案,但是这样会多算一部分,也就是另一端点和询问点没有跨过分治中心,要减去这部分的答案。
如模板题,用两棵线段树维护两部分,再相减。
int qry(int u,int k){
int res=0;
for(int nw=u,pre=0;nw;pre=nw,nw=divfa[nw]){
int d=k-dis(u,nw);
if(d<0) continue;
res+=A.query(nw,d);
if(pre) res-=B.query(pre,d);
}
return res;
}
修改也是非常简单地向上暴力跳就好了,一个点会被上面所有分治中心管辖,依次修改 \(O(\log n)\) 次。
void upd(int u,int val){
for(int nw=u;nw;nw=divfa[nw]){
A.modify(nw,dis(nw,u),val);
if(divfa[nw]) B.modify(nw,dis(divfa[nw],u),val);
}
}
如果要实现类似于“在 lca 合并路径”的操作,如 Qtree IV,可以用三个可删堆维护,维护在每个分治中心合并的情况:
struct Heap{
priority_queue<int> x,y;
void Push(int t){ x.push(t); }
void Del(int t){ y.push(t); }
void adjust(){ while(!y.empty() && x.top()==y.top()) x.pop(),y.pop(); }
void Pop(){ adjust(); if(x.size()) x.pop(); }
int Sz(){ return x.size()-y.size(); }
int Top(){ if(!Sz()) return -inf; adjust(); return x.top(); }
int Sec(){ if(Sz()<2) return -inf; int t=Top(); Pop(); int t2=Top(); Push(t); return t2; }
}hp[maxn],hp2[maxn],ans;
void addval(int u,int x){
if(hp[u].Sz()>=2)
ans.Del(hp[u].Top()+hp[u].Sec());
hp[u].Push(x);
if(hp[u].Sz()>=2)
ans.Push(hp[u].Top()+hp[u].Sec());
}
void delval(int u,int x){
if(hp[u].Sz()>=2)
ans.Del(hp[u].Top()+hp[u].Sec());
hp[u].Del(x);
if(hp[u].Sz()>=2)
ans.Push(hp[u].Top()+hp[u].Sec());
}
void Add(int u)
{
addval(u,0);
for(int nw=u;dfa[nw];nw=dfa[nw])
{
int presz=hp2[nw].Sz(),pretop=hp2[nw].Top();
int d=dis(u,dfa[nw]);
if(!presz || d>pretop){
if(presz) delval(dfa[nw],pretop);
addval(dfa[nw],d);
}
hp2[nw].Push(d);
}
}
void Del(int u)
{
delval(u,0);
for(int nw=u;dfa[nw];nw=dfa[nw])
{
int pretop=hp2[nw].Top();
int d=dis(u,dfa[nw]);
hp2[nw].Del(d);
if(pretop==d){
delval(dfa[nw],d);
if(hp2[nw].Sz()) addval(dfa[nw],hp2[nw].Top());
}
}
}

浙公网安备 33010602011771号