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);
        }
    }
  • 相关阅读:
    ZOJ 3818 Pretty Poem
    HDU 4597 Play Game
    HDU 4497 GCD and LCM
    CSU 1335 高桥和低桥
    UVA 10791 Minimum Sum LCM
    CSU 1119 Collecting Coins
    CSU 1120 病毒
    UVA 12169 Disgruntled Judge
    HDU 1301 Jungle Roads
    POJ 1258 Agri-Net
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10727132.html
Copyright © 2011-2022 走看看