首页 > 代码库 > BZOJ 4668 冷战

BZOJ 4668 冷战

这题首先应该想lct的做法:每次link一个递增的边权,查询两点边权最大值。

后来发现按秩合并的并查集可以搞。复杂度nlogn可过。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxn 500500using namespace std;int n,m,type,x,y,lastans=0,fath[maxn],rank[maxn],dep[maxn],times=0,val[maxn];int getfather(int x){    if (fath[x]==x) return x;    int ret=getfather(fath[x]);    dep[x]=dep[fath[x]]+1;    return ret;}int lca(int x,int y){    int ans=0;    while (x!=y)    {        if (dep[x]<dep[y]) swap(x,y);        ans=max(ans,val[x]);        x=fath[x];    }    return ans;}int main(){    scanf("%d%d",&n,&m);    for (int i=1;i<=n;i++)        fath[i]=i;    for (int i=1;i<=m;i++)    {        scanf("%d%d%d",&type,&x,&y);        x^=lastans;y^=lastans;        if (type==0)        {            times++;            int px=getfather(x),py=getfather(y);            if (rank[px]>=rank[py])            {                fath[py]=px;                val[py]=times;                if (rank[px]==rank[py]) rank[px]++;            }            else            {                fath[px]=py;                val[px]=times;            }        }        else        {            int px=getfather(x),py=getfather(y);            if (px!=py) {lastans=0;printf("%d\n",lastans);}            else            {                lastans=lca(x,y);                printf("%d\n",lastans);            }        }    }    return 0;}

 

BZOJ 4668 冷战