Cod sursa(job #1326128)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 24 ianuarie 2015 18:53:06
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.92 kb
#include <bits/stdc++.h>

using namespace std;

const int INF = ( 1U << 31 ) - 1;
const int MAX_LEVEL = 30;
const int SIZE_SKIPLIST = 2000000;

int SL[SIZE_SKIPLIST];
int levelNode[MAX_LEVEL];
int pointer, maxLevel;

double getMemory()
{
    return (double)sizeof( SL ) / 1024.0 / 1024.0;
}

void initSkiplist()
{
    srand( time( NULL ) );

    SL[0] = -INF;

    for ( int i = 0; i < MAX_LEVEL; ++i )
        SL[i + 1] = MAX_LEVEL + 1;

    SL[MAX_LEVEL + 1] = INF;

    pointer = MAX_LEVEL + 2;
    maxLevel = 1;
}

inline int generateLevel()
{
    int level = 1;

    for ( int R = rand() % ( 1 << (MAX_LEVEL - 1) ); ( R & 1 ) == 1; R >>= 1 )
        level++;

    assert( level < MAX_LEVEL );

    return level;
}

void insert(const int value)
{
    int current = 0;

    for ( int l = maxLevel - 1; l >= 0; l-- )
    {
        while ( SL[ SL[current + l + 1] ] < value )
            current = SL[current + l + 1];

        levelNode[l] = current;
    }

    current = SL[current + 1];

    if ( value != SL[current] )
    {
        int newLevel = generateLevel();

        if ( newLevel > maxLevel )
        {
            for ( int l = maxLevel; l < newLevel; ++l )
                levelNode[l] = 0;

            maxLevel = newLevel;
        }

        SL[pointer] = value;

        for ( int l = 0; l < newLevel; ++l )
        {
            SL[pointer + l + 1] = SL[levelNode[l] + l + 1];
            SL[levelNode[l] + l + 1] = pointer;
        }

        pointer += newLevel + 1;

        assert( pointer < SIZE_SKIPLIST );
    }
}

bool find(const int value)
{
    int current = 0;

    for ( int l = maxLevel - 1; l >= 0; l-- )
    {
        while ( SL[ SL[current + l + 1] ] < value )
            current = SL[current + l + 1];
    }

    current = SL[current + 1];

    return ( value == SL[current] );
}

void erase(const int value)
{
    int current = 0;

    for ( int l = maxLevel - 1; l >= 0; l-- )
    {
        while ( SL[ SL[current + l + 1] ] < value )
            current = SL[current + l + 1];

        levelNode[l] = current;
    }

    current = SL[current + 1];

    if ( SL[current] == value )
    {
        for ( int l = 0; l < maxLevel && SL[levelNode[l] + l + 1] == current; ++l )
            SL[levelNode[l] + l + 1] = SL[current + l + 1];
    }
}

void printList()
{
    int current = 0;

    while ( SL[current] != INF )
    {
        cerr << SL[current] << " ";
        current = SL[current + 1];
    }
}

int main()
{
    cerr << fixed << setprecision( 10 );
    cerr << "Memory: " << getMemory() << "\n";

    initSkiplist();

    ifstream in("hashuri.in");
    ofstream out("hashuri.out");

    ios_base::sync_with_stdio( false );

    int N;
    in >> N;

    while ( N-- )
    {
        int tip, x;

        in >> tip >> x;

        switch(tip)
        {
            case 1: insert(x); break;
            case 2: erase(x); break;
            case 3: out << find(x) << "\n"; break;

            default: cerr << "Error\n";
        }
    }

    return 0;
}