探究不同进制的树上倍增
探究不同进制的树上倍增
将以 \(2\) 为底变成以 \(x\) 为底。
那么每一位最多要跳 \(x-1\) 次,扫描 \(1\) 次。
跳一次时间复杂度 \(\mathcal O(x\log_{x} n)。\)
代码,以 \(16\) 进制为例。
预处理部分:
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
inline 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...\) 只能用于时间换空间。