Cod sursa(job #1398698)

Utilizator danalex97Dan H Alexandru danalex97 Data 24 martie 2015 12:49:36
Problema Schi Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;

const int N = 30010;

ifstream F("schi.in");
ofstream G("schi.out");

struct item {
    double key;
    int pr,sz,vl;
    item *l , *r;
    item() {
    }
    item(double k,int vv) {
        key = k;
        pr = (rand() << 16) ^ rand();
        l = r = NULL;
        sz = 1;
        vl = vv;
    }
};

#define tree item*

void compute(tree &t)
{
    if ( t == NULL ) return;
    t->sz = 1;
    if ( t->l != NULL ) t->sz += t->l->sz;
    if ( t->r != NULL ) t->sz += t->r->sz;
}

void split(tree t,int key,tree &l,tree &r)
{
    if ( !t )
    {
        l = r = NULL;
    }
    else
        if ( key < t->key )
        {
            split(t->l,key,l,t->l);
            r = t;
        }
        else
        {
            split(t->r,key,t->r,r);
            l = t;
        }
    compute(l);
    compute(r);
}

void insert(tree& t,tree x)
{
    if ( !t )
        t = x;
    else
        if ( x->pr > t->pr )
        {
            split(t,x->key,x->l,x->r); // taie t in copii lui x
            t = x;
        }
        else
        {
            if ( x->key < t->key ) // ma uit in care fiu il pun
                insert( t->l , x );
            else
                insert( t->r , x );
        }
    compute(t);
}

void merge(tree& t,tree l,tree r)
{
    if ( !l || !r )
        t = l ? l : r;
    else
        if ( l->pr > r->pr )
        {
            merge(l->r,l->r,r); // unesc fiul drept ai lui l cu right
            t = l;
        }
        else
        {
            merge(r->l,l,r->l);
            t = r;
        }
    compute(t);
}

void erase(tree &t,int key)
{
    if ( t->key == key )
        merge(t,t->l,t->r);
    else
    {
        if ( key < t->key )
            erase(t->l,key);
        else
            erase(t->r,key);
    }
    compute(t);
}

double go_to(tree t,int pl)
{
    int co = 0;
    if ( t->l != NULL )
        co = t->l->sz;
    if ( pl == co + 1 )
        return t->key;
    if ( co >= pl )
        return go_to(t->l,pl);
    else
        return go_to(t->r,pl-co-1);
}

void print(tree t)
{
    if ( t->l )
        print(t->l);
    G<<t->vl<<'\n';
    if ( t->r )
        print(t->r);
}

void printd(tree t)
{
    if ( t->l )
        printd(t->l);
    cerr<<t->vl<<' ';
    if ( t->r )
        printd(t->r);
}

tree t = NULL;

int n,a,b;

double f(double l,double r)
{
    return l + (r-l) / 2.5;
}

const int sz = 30000;

int main()
{
    srand(time(0));
    F>>n;
    F>>a>>b;
    if ( a == 1 && b == 1 )
    {
        tree q = new item(sz,1);
        insert(t,q);
        q = new item(0,2);
        insert(t,q);
    }
    else
    {
        tree q = new item(0,1);
        insert(t,q);
        q = new item(sz,2);
        insert(t,q);
    }
    //printd(t); cerr<<'\n';
    for (int i=3,x;i<=n;++i)
    {
        F>>x;
        tree q;
        if ( x == 1 )
            q = new item( go_to(t,x) - sz , i );
        else
            if ( x == i )
                q = new item( go_to(t,x-1) + sz , i );
            else
                q = new item( f(go_to(t,x-1),go_to(t,x)) , i );
        insert(t,q);
        //printd(t); cerr<<'\n';
    }
    print(t); G<<'\n';
}