Cod sursa(job #492281)

Utilizator purdea.andreiPurdea Andrei purdea.andrei Data 14 octombrie 2010 07:14:52
Problema Schi Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.69 kb
#define D if(1)
#include <stdio.h>
#include <stdlib.h>
//2:54 total time of impl

#define N 10000

int p[N]; // parent
int l[N]; // left
int r[N]; // right
int k[N]; // key
int c[N]; // color , 0 = red
int o[N]; // for order statistics

int root = 0;
int firstfree = 1;
int del[N]; // list of deleted indexes
int del_n = 0; // number of deleted indexes

int newindex() {
    if (del_n>0)
        return del[del_n--];
    return firstfree++;
}

void rotleft(int index) {
    int b, x, par;
    b = l[r[index]];
    x = r[index];
    par = p[index];
    
    if (b!=0)
        p[b] = index;
    r[index] = b;
    
    p[index] = x;
    l[x] = index;
    
    p[x] = par;
    if (par==0)               root = x;
    else if (l[par] == index) l[par] = x;
    else                      r[par] = x;
    
    o[index] = o[l[index]] + p[r[index]] + 1;
    o[x] = o[l[x]] + o[r[x]] + 1;
}


void rotright(int index) {
    int b, x, par;
    b = r[l[index]];
    x = l[index];
    par = p[index];
    
    if (b!=0)
        p[b] = index;
    l[index] = b;
    
    p[index] = x;
    r[x] = index;
    
    p[x] = par;
    if (par==0)               root = x;
    else if (r[par] == index) r[par] = x;
    else                      l[par] = x;
    
    o[index] = o[l[index]] + p[r[index]] + 1;
    o[x] = o[l[x]] + o[r[x]] + 1;
}

int findord(int ord) {
    int i = root;
    while (i!=0) {
        if (o[l[i]]+1==ord) break;
        else {
            if (o[l[i]]>=ord) i = l[i];
            else {
                 ord = ord - o[l[i]] - 1;
                 i = r[i];}
        }
    }
    return i;
}

void insert_rep(int);
void insert(int key, int ord) {
    int newi = newindex();
    int over, par, i;
    if (root==0) {
        root=newi;
        p[newi] = 0;
    } else {
        over = findord(ord);
        if (over==0) {
            par = root;
            while (r[par]!=0) par = r[par];
            r[par] = newi;
        } else {
            par = over;
            if (l[par]==0) l[par] = newi;
            else {
                par = l[over];
                while (r[par]!=0) par = r[par];
                r[par] = newi;
            }
        }
        p[newi] = par;
    }
    l[newi] = r[newi] = c[newi] = 0;
    k[newi] = key;
    i = newi;
    while (i!=0) {
        o[i] = o[l[i]] + o[r[i]] + 1;
        i = p[i];
    }
    insert_rep(newi);
}
void insert_rep(int i) {
    while (c[p[i]]==0 && i!=root) {
        if (l[p[p[i]]] == p[i]) {
            if (c[r[p[p[i]]]] == 0) {
                c[r[p[p[i]]]] = 1;
                c[p[i]] = 1;
                c[p[p[i]]] = 0;
                i = p[p[i]];
            } else {
                if (r[p[i]] == i) {
                    rotleft(p[i]);
                    i = l[i];
                }
                rotright(p[p[i]]);
                c[p[i]] = 1;
                c[r[p[i]]] = 0;
                break;
            }
        } else {
            if (c[l[p[p[i]]]] == 0) {
                c[l[p[p[i]]]] = 1;
                c[p[i]] = 1;
                c[p[p[i]]] = 0;
                i = p[p[i]];
            } else {
                if (l[p[i]] == i) {
                    rotright(p[i]);
                    i = r[i];
                }
                rotleft(p[p[i]]);
                c[p[i]] = 1;
                c[l[p[i]]] = 0;
                break;
            }

        }
    }
    c[root] = 1;
}
void bwrite(int i) {
    if (i==0) return;
    bwrite(l[i]);
    printf("%d\n", k[i]);
    bwrite(r[i]);
}



int main() {
    int n, i;
    c[0] = 1; // INITIALIZE, IMPORTANT!!!
    freopen("schi.in", "r", stdin);
    freopen("schi.out", "w", stdout);
    scanf("%d", &n);
    for (i=0;i<n;i++) {
        int t;
        scanf("%d", &t);
        insert(i+1, t);
    }
    bwrite(root);
    return 0;
}