Cod sursa(job #1322238)

Utilizator RaileanuCristian Raileanu Raileanu Data 19 ianuarie 2015 21:38:55
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 6.17 kb
#include <fstream>
#include<iostream>
using namespace std;
#define MX 1000005
int st[MX],dr[MX], val[MX], c[MX], h[MX],bal[MX], nrn, rad, stiva[MX],k ; // k e varful stivei
ifstream f1("hashuri.in");                               // h inaltimea
ofstream f2("hashuri.out");

void swap_n(int x, int y)
{
    swap(st[x],st[y] );
    swap(dr[x],dr[y] );
    swap(c[x],c[y] );
    swap(val[x],val[y] );

}

void rotatie(int nod, int mod )
{
    int p,q;
    if (mod==1)
        {                   // rotatie SS
            p= st[nod];
            swap_n(nod,p );
            st[p]=dr[nod];
            dr[nod]=p;
            h[p]= h[dr[p] ]+1; // recalculam inaltimea
        }
    if (mod==2)             // rotatie SD
        {
            p= st[nod];
            q= dr[p];
            swap(val[nod], val[q] );
            swap(c[nod],c[q] );
            dr[p]= st[q];
            st[q]=dr[q];
            dr[q]=dr[nod];
            dr[nod]=q;

            h[q]= h[p]= h[st[p] ]+1;
        }
    if (mod==3)             // rotatie DD
        {
            p= dr[nod];
            swap_n(nod,p); // intersch st , dr, c, val - lui nod si p
            dr[p]=st[nod];
            st[nod]=p;

            h[p ]= h[st[p] ]+1;
        }
    if (mod==4)             // rotatie SD
        {
            p= dr[nod];
            q= st[p];
            swap(val[nod],val[q] );
            swap(c[nod], c[q] );
            st[p]=dr[q];
            dr[q]=st[q];
            st[q]= st[nod];
            st[nod]=q;

            h[q]= h[p]= h[st[p] ]+1;
        }
}

void echilib_avl(int nod)
{
    bal[nod] = h[dr[nod] ]-h[st[nod] ];

    if (bal[nod] ==-2 )
        { if (bal[st[nod] ]==-1 )   // rotatie SS
                rotatie(nod,1);
                else                // rotatie SD
                rotatie(nod,2);
            bal[nod]=0;
        }

    if (bal[nod]==2 )
    {
        if (bal[dr[nod] ]==1 )  // rotatie DD
                rotatie(nod,3);
            else                // rotatie DS
                rotatie(nod,4);
            bal[nod]=0;
    }

    if (st[nod] || dr[nod] )         // calculez inaltimea subarborelui
        h[nod]=max(h[st[nod] ], h[dr[nod] ] )+1;
}

void add(int nod, int a)
{
    if (!val[nod])
        {val[++nrn]=a; c[nrn]=1; rad=nrn; return; } // creeaza radacina

    if (a== val[nod] )
           { c[nod]++; return; }

    if (a<val[nod] )
    {
        if (st[nod] )
                add(st[nod],a );
            else {val[++nrn]=a; st[nod]=nrn; c[nrn]=1; }
    }
    else
    {
        if (dr[nod] )
            add(dr[nod],a );
            else {val[++nrn]=a; dr[nod]=nrn; c[nrn]=1; }
    }
    // fucking patch for AVL :))
    echilib_avl(nod);
}

void SRD(int nod)
{
    if (!nod) return;
    SRD(st[nod] );
    for (int i=1; i<=c[nod];i++)
        cout<<val[nod]<<" ";
    SRD(dr[nod] );
}

void SDR(int nod)
{
    if (!nod) return;

    SDR(st[nod]);
    SDR(dr[nod] );
    for (int i=1; i<=c[nod];i++)
        cout<<val[nod]<<" ";
}

int caut(int nod, int x)
{
    if (!nod)
        return 0;

    if (x==val[nod] )
        return nod;
    else
        if (x< val[nod] )
            return caut(st[nod],x );
        else return caut(dr[nod],x );
}

int el_max(int nod)
{
    if (!dr[nod] )
        return val[nod];

    return el_max(dr[nod] );
}

void sterge_nod(int x)   // iterativa
{
    int p=rad, nod=rad, q;
    while (x!=val[nod] && nod )
        {   p=nod;
            stiva[++k]=p;
            if (x < val[nod] ) nod=st[nod];
                else nod=dr[nod]; }
        // nod - nodul pt sters; p - parintele lui ;   rad - radacina arborelui (globala )
    if (nod ) // stergem nodul
        if (nod==p)  // nod e radacina
        {
            if (!st[nod] )
                rad= dr[nod];

            if (!dr[nod] )
                rad= st[nod];

            if (st[nod] && dr[nod] ) // nod are ambii fii
            {
                q=st[nod];      // q va fi noul tata a fiului drept a lui nod
                while (dr[q] )  // cautam alt tata pt fiul drept
                    q=dr[q];

                dr[q]= dr[nod];     //mutam fiul drept la noul tata
                rad= st[rad];     // radacina devine stanga sa
            }
        }
        else if (nod== st[p] ) // nod e fiul stang <-
        {
            if (!st[nod] )            // nod nu are fiul stang
                st[p]=dr[nod];        // fiul stang a lui p va fi fiul drept a lui nod

            if (!dr[nod] )            // nod nu are fiul drept
                st[p]= st[nod];
            // daca nod nu are nici un fiu, fiul stang a lui p va fi 0, deci nu exista
            if (st[nod] && dr[nod] ) // nod are ambii fii
            {
                q=st[nod];      // q va fi noul tata a fiului drept a lui nod
                while (dr[q] )  // cautam alt tata pt fiul drept
                    q=dr[q];

                dr[q]=dr[nod];     //mutam fiul drept la noul tata
                st[p]= st[nod];     // noul fiu stang a lui p e fiul stang a lui nod
            }
        }
        else    // nod e fiul drept ->
        {
            if (!st[nod] )
                dr[p]=dr[nod];

            if (!dr[nod] )
                dr[p]=st[nod];

            if (st[nod] && dr[nod] ) // nod are ambii fii
            {
                q=st[nod];      // q va fi noul tata a fiului drept a lui nod
                while (dr[q] )  // cautam alt tata pt fiul drept
                    q=dr[q];

                dr[q]=dr[nod];     //mutam fiul drept la noul tata
                dr[p]= st[nod];     // noul fiu drept a lui p e fiul stang a lui nod
            }
        }
    // fucking patch for avl :))
    while (k>0)
        echilib_avl(stiva[k--] );
}



void afis(int a[], int n )
{
    cout<<"\n";
    for (int i=1; i<=n; i++)
        cout<<a[i]<<" ";
}

int main( )
{
    h[0]=-1; // necesar

    int op,a,n,i;
    f1>>n;
    for (i=1; i<=n; i++)
    {
        f1>>op>>a;
        if (op==1) add(rad,a);
        if (op==2) sterge_nod(a);
        if (op==3) f2<< (caut(rad,a) != 0)<<"\n";
    }

    f2.close();
    return 0;
}