探究不同进制的树上倍增

探究不同进制的树上倍增

将以 \(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...\) 只能用于时间换空间。

posted @ 2022-07-05 15:47  cjlworld  阅读(36)  评论(0编辑  收藏  举报