LCA

倍增求LCA

错误的\(dfs\)

void dfs(int u,int fa){
       dep[u]=dep[fa]+1;
       f[u][0]=fa;
       for(int i=head[u];i;i=e[i].next){
           int v=e[i].to;
           if(v==fa)continue;
           dfs(v,u);
       }
       for(int i=1;(1<<i)<=dep[u];++i){
           f[u][i]=f[f[u][i-1]][i-1];
       }
   }

正确的\(dfs\)

void dfs(int u,int fa){
       dep[u]=dep[fa]+1;
       for(int i=1;(1<<i)<=dep[u];++i){
           f[u][i]=f[f[u][i-1]][i-1];
       }
       for(int i=head[u];i;i=e[i].next){
           int v=e[i].to;
           if(v==fa){
               continue;
           }
           f[v][0]=u;
           dfs(v,u);
       }
    }

唯一的区别在于什么时候处理\(f\)数组,错误的码在叶子节点处理,但是显然叶子节点往上的节点都没有值,这样递推\(f\)中应该大部分都是错误的(然而在一些小数据中体现的不明显,所以我一直这么错还一直怀疑数据的锅)

倍增求LCA

\(O(\log n)\)

int Lca(int u,int v){
       if(dep[u]<dep[v])swap(u,v);
       int len=dep[u]-dep[v],k=0;
       while(len){
           if(len&1){
               u=f[u][k];
           }
           len>>=1;k++;
       }
       if(u==v)return u;
       for(int i=20;i>=0;--i){
           if(f[u][i]!=f[v][i]){
               u=f[u][i];
               v=f[v][i];
           }
       }
       return f[u][0];
   }

另外还有ST表RMQ,树链剖分的求法,请到其他大佬的博客学习

posted @ 2022-05-13 09:14  Chano_sb  阅读(37)  评论(0)    收藏  举报