题目描述:
雾。
题目分析:
左偏树裸题,注意朋友的朋友也是朋友,用并查集来维护关系
题目链接:
Ac 代码:
#include <iostream>
#include <cstdio>
#include <cstring>
const int maxm=110000;
struct left_tree{
int v,ls,rs,dis;
}st[maxm];
int fa[maxm],rt[maxm],n;
int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
if(st[x].v<st[y].v) std::swap(x,y);
st[x].rs=merge(st[x].rs,y);
if(st[st[x].ls].dis<st[st[x].rs].dis) std::swap(st[x].ls,st[x].rs);
st[x].dis=st[st[x].rs].dis+1;
return x;
}
inline int pop(int x)
{
int d=merge(st[x].ls,st[x].rs);
st[x].ls=st[x].rs=0;
return d;
}
void work()
{
memset(rt,0,sizeof(rt));
for(int i=1;i<=n;i++)
{
scanf("%d",&st[i].v);
st[i].ls=st[i].rs=st[i].dis=0;
rt[i]=merge(rt[i],i);
fa[i]=i;
}
int m;
scanf("%d",&m);
for(int i=1,now;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
if(find(u)==find(v))
{
printf("-1\n");
continue;
}
int f1=find(u),f2=find(v);
now=rt[f1];
rt[f1]=pop(now);
st[now].v=st[now].v/2;
rt[f1]=merge(rt[f1],now);
now=rt[f2];
rt[f2]=pop(now);
st[now].v/=2;
rt[f2]=merge(rt[f2],now);
fa[f1]=f2;
rt[f2]=merge(rt[f2],rt[f1]);
printf("%d\n",st[rt[f2]].v);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
work();
return 0;
}