探究不同进制的树上倍增
探究不同进制的树上倍增
将以 2 为底变成以 x 为底。
那么每一位最多要跳 x-1 次,扫描 1 次。
跳一次时间复杂度 \mathcal O(x\log_{x} n)。
代码,以 16 进制为例。
预处理部分:
copy for(i=1;i<=n;i++) up[i][0]=fa[i];
for(j=1;j<=5;j++)
for(i=1;i<=n;i++) {
up[i][j]=up[i][j-1];
for(k=1;k<16;k++)
up[i][j]=up[up[i][j]][j-1];
}
求 lca
copyinline int lca(rint x,rint y)
{
if(dep[x]<dep[y]) swap(x,y); // 让 x 的深度更大,跳 x.
for(rint k=dep[x]-dep[y],i=0,j;k;i++,k>>=4)
for(j=(k&15);j;j--) x=up[x][i];
if(x==y) return x;
for(rint i=5;i>=0;i--)
while(up[x][i]!=up[y][i])
x=up[x][i],y=up[y][i];
return up[x][0];
}
实践 证明 x=2 时跑得最快,因此取 x=4,8,16... 只能用于时间换空间。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步