Pre-knowledge: a binary heap
First, we define the external node to the left or right son son empty node, the node outside the definition of dist is zero, empty nodes dist is -1, dist other nodes in its sub-tree in the distance outside the nearest node plus One.
So, what's left side tree? Leftist tree is a binary tree , which not only has the nature of the heap , and is the "left side" : Each node son left dist greater than equal to the right son of dist , in addition, each node dist dist son for the right +1.
Left side is a tree can stack and the combined process of reference to the following code:
#define LS S [X] .son [0] #define RS S [X] .son [. 1] struct Node { int DIS, Val, Son [ 2 ], RT; } S [ 150010 ]; int Merge ( int X , int Y) { // this is the root of a small stack combined IF (X || Y)!! return X + Y; // a stack to another stack return null IF (S [X] .val> S [ Y] .val || (S [X] .val == S [Y] .val && X> Y)) the swap (X, Y); // because rootlets stack, so a small value in the preceding rs = merge (RS, y); // put x, so that as the root of the right son of the root y recursively combined with another small to meet because of the nature of a binary heap IF (S [LS] .dis <S [RS] .dis ) swap (LS, rs); //Because the nature left to meet his son's son dist dist larger than the right of S [LS] .rt = S [rs] .rt = .rt the X-S = [the X-]; // the root itself around his son and father are set root itself S [X] = S .dis [RS] + .dis . 1 ; // the root dist dist defined as a right son. 1 + dist; return X; // return new root }
Further find a stack top of the stack may be disjoint-set path compression optimization, namely:
int GET ( int X) { // disjoint-set compression path IF (S [X] .rt == X) return X; S [X] .rt = GET (S [X] .rt); return S [ X] .rt; }
If you want to delete a point:
void POP ( int X) { S [X] .val = - . 1 ; // puncturing point is his own weight to -1 S [LS] .rt = LS; S [RS] .rt = RS; / / about his son's father about his son set itself S [the X-] .rt = merge (LS, rs); // remember his father about his son delete the original point of merging deleted point to the new root (because you just deleted a point that does not make the stack into two) }
So this question came out of the code:
#include<bits/stdc++.h> #define ls s[x].son[0] #define rs s[x].son[1] using namespace std; int n,t,a,b,c; struct node{ int dis,val,son[2],rt; }s[150010]; int merge(int x,int y){ if(!x||!y)return x+y; if(s[x].val>s[y].val||(s[x].val==s[y].val&&x>y))swap(x,y); rs=merge(rs,y); if(s[ls].dis<s[rs].dis)swap(ls,rs); s[ls].rt=s[rs].rt=s[x].rt=x; s[x].dis=s[rs].dis+1; return x; } int get(int x){ if(s[x].rt==x)return x; s[x].rt=get(s[x].rt); return s[x].rt; } void pop(int x){ s[x].val=-1; s[ls].rt=ls; s[rs].rt=rs; s[x].rt=merge(ls,rs); } int main(){ cin>>n>>t; s[0].dis=-1; for(int i=1;i<=n;i++){ s[i].rt=i; scanf("%d",&s[i].val); } for(int i=1;i<=t;i++){ scanf("%d%d",&a,&b); if(a==1){ scanf("%d",&c); if(s[b].val==-1||s[c].val==-1)continue; int B=get(b),C=get(c); if(B!=C){ s[B].rt=s[C].rt=merge(B,C); } }else{ if(s[b].val==-1)printf("-1\n"); else printf("%d\n",s[get(b)].val),pop(get(b)); } } return 0; }
Recommend a few questions?
Luo Gu 1456 monkey king
Luo Gu 2713 Rome Games
Also it can be heard and heap have stl, at #