zoukankan      html  css  js  c++  java
  • BZOJ 4668: 冷战 并查集&&暴力LCA(雾)

    利用并查集按秩合并,保存每个点合并的时间;

    求时间时,就一直跳u=fa[u],并记录路径上时间的最大值,代表最后一次合并的时间;

    因为树高是$log$的,所以时间复杂度是$mathcal{O}(mlogn)$

    #include<cstdio>
    #include<iostream>
    #define R register int
    const int N=500010;
    using namespace std;
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    }
    int n,m,tim,lst;
    int fa[N],t[N],d[N],rk[N];
    int getf(int x) {
        if(x==fa[x]) return x;
        R ret=getf(fa[x]);
        d[x]=d[fa[x]]+1; return ret;
    }
    inline void merge(int u,int v) { ++tim;
        u=getf(u),v=getf(v);
        if(u==v) return;
        if(rk[u]>=rk[v]) fa[v]=u,t[v]=tim;
        else fa[u]=v,t[u]=tim;
        if(rk[u]==rk[v]) ++rk[u];
    }
    inline int ask(int u,int v) { R ans=0;
        if(getf(u)!=getf(v)) return 0;
        if(d[u]<d[v]) swap(u,v);
        while(d[u]!=d[v]) ans=max(ans,t[u]),u=fa[u];
        while(u!=v) ans=max(ans,max(t[u],t[v])),u=fa[u],v=fa[v];
        return ans;
    }
    signed main() {
        n=g(),m=g(); for(R i=1;i<=n;++i) fa[i]=i,rk[i]=1,d[i]=0;
        for(R i=1;i<=m;++i) {
            R k=g(),u=g(),v=g(); u^=lst,v^=lst;
            if(k) printf("%d
    ",lst=ask(u,v));
            else merge(u,v);
        }
    }
  • 相关阅读:
    计算机的运算方法
    干货 Elasticsearch 知识点整理 一
    深入理解 Spring finishBeanFactoryInitialization
    Git 学习笔记
    深入理解 Mybatis
    深入理解 MyBatis 启动流程
    MyBatis 开发手册
    深入理解SpringMvc 启动流程
    深度长文回顾web基础组件
    快速排序
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10727132.html
Copyright © 2011-2022 走看看