public static TreapNode Merge(TreapNode a, TreapNode b)
 {
     if (a == null || b == null)
     {
         return(a ?? b);
     }
     if (rand.NextDouble() < (double)GetSize(a) / (GetSize(a) + GetSize(b)))
     {
         a.PutDown();
         if (a.r != null)
         {
             a.r.parent = null;
         }
         a.r        = Merge(a.r, b);
         a.r.parent = a;
         a.Maintain();
         return(a);
     }
     else
     {
         b.PutDown();
         if (b.l != null)
         {
             b.l.parent = null;
         }
         b.l        = Merge(a, b.l);
         b.l.parent = b;
         b.Maintain();
         return(b);
     }
 }
 public static void Split(TreapNode o, out TreapNode a, out TreapNode b, int position)
 {
     if (position < 0)
     {
         MyLogger.Log($"TreapNode: position = {position}");
         position = 0;
     }
     if (position > GetSize(o))
     {
         MyLogger.Log($"TreapNode: position = {position}");
         position = GetSize(o);
     }
     //MyLogger.Assert(0 <= position && position <= GetSize(o));
     if (o == null)
     {
         a = b = null; return;
     }
     o.PutDown();
     if (position <= GetSize(o.l))
     {
         b = o;
         if (b.l != null)
         {
             b.l.parent = null;
         }
         Split(b.l, out a, out b.l, position);
         if (b.l != null)
         {
             b.l.parent = b;
         }
         b.Maintain();
     }
     else
     {
         a = o;
         if (a.r != null)
         {
             a.r.parent = null;
         }
         Split(a.r, out a.r, out b, position - GetSize(a.l) - 1);
         if (a.r != null)
         {
             a.r.parent = a;
         }
         a.Maintain();
     }
 }