COGS[526] 爱争吵的猴子
左偏树模板。
// q.c #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int M=100000+10; /*******************************************************************/ int cnt,rt[M],f[M],lc[M],rc[M],dis[M],val[M]; int reset(int x) { ++cnt,f[cnt]=lc[cnt]=rc[cnt]=dis[cnt]=0,val[cnt]=x; return cnt; } int finds(int x) { for(;f[rt[x]];rt[x]=f[rt[x]]); return rt[x]; } int dist(int x) { return x?dis[x]:-1; } int merge(int x,int y) { if(!x) return y; if(!y) return x; if(val[x]<val[y]) swap(x,y); rc[x]=merge(rc[x],y); if(rc[x]) f[rc[x]]=x; if(dist(rc[x])>dist(lc[x])) swap(lc[x],rc[x]); dis[x]=dist(rc[x])+1; return x; } void UP(int x) { f[x]=lc[x]=rc[x]=dis[x]=0,val[x]/=2; } /*******************************************************************/ int main() { freopen("monkeyk.in","r",stdin); freopen("monkeyk.out","w",stdout); int n,m,a,b,c,d; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a); rt[i]=reset(a); } scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); a=finds(a); b=finds(b); if(a==b) { printf("%d\n",-1); continue; } c=merge(lc[a],rc[a]); d=merge(lc[b],rc[b]); if(c) f[c]=0; if(d) f[d]=0; UP(a),UP(b); a=merge(a,b); c=merge(c,d); c=merge(a,c); printf("%d\n",val[c]); } return 0; }