예제 #1
0
 forn(q,Q)
 {
     char op[8];
     scanf("%s", op);
     if (op[0] == 'I')
     {
         int x,y;
         scanf("%d%d", &x,&y);
         x--;
         // Esto es parecido (pero bien diferente :P) al codigo de insertarAUnladoPointer, pero empezando en p en lugar de en root
         // De entrada me comi que era hacer lo mismo exacto que insertarAUnLado, y pegue WA.
         // Y luego me comi otro WA por olvidarme la linea p = p->h(0); :P
         // Moraleja: esto seria bastante mas error prone que el split obvio.
         Nodo<Datos> *p = iesimo(x, t), *nodo = new Nodo<Datos>(y);
         int lado = 0;
         if (p->h(0))
         {
             p = p->h(0);
             lado = 1;
             while (p->h(1)) p = p->h(1);
         }
         p->hang(lado, nodo);
         nodo->flotar();
         t.reroot();
     }
     else if (op[0] == 'D')
     {
         int x;
         scanf("%d", &x);
         x--;
         t.erasePointer(iesimo(x, t));
     }
     else if (op[0] == 'R')
     {
         int x,y;
         scanf("%d%d", &x, &y);
         x--;
         Nodo<Datos> *p = iesimo(x, t);
         p->dat.x = y;
         p->fullUpdate();
     }
     else if (op[0] == 'Q')
     {
         int x,y;
         scanf("%d%d", &x,&y);
         x--;
         assert(x < y);
         Treap<Datos> t2,t3;
          t.splitPointer(iesimo(x, t), t2);
         t2.splitPointer(iesimo(y-x, t2), t3);
         printf("%d\n", t2.root->dat.bestSum);
         t.merge(t2);
         t.merge(t3);
     }
     else
         assert(false);
 }
예제 #2
0
Nodo<Datos> *iesimo(int i, Treap<Datos> &t)
{
    Nodo<Datos> *p = t.root;
    while (true)
    {
        assert(p);
        int L = tam(p->h(0));
        if (i < L)
            p = p->h(0);
        else if (i == L)
            return p;
        else
        {
            i -= L + 1;
            p = p->h(1);
        }
    }
}