Cod sursa(job #492283)

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

#define N 30020

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

void printarb(int i, int d) {
    int kk;
    if (i==0) return;
    printarb(r[i], d+1);
    for (kk=0;kk<d;kk++) printf("    ");
    printf("%d, c: %d; p(%d) o(%d)\n", k[i], c[i], k[p[i]], o[i]);
    printarb(l[i], d+1);
}


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]] + o[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]] + o[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 {
            D printf("ord: %d    ;   ", ord);
            if (o[l[i]]>=ord) i = l[i];
            else {
                 ord = ord - o[l[i]] - 1;
                 i = r[i];
            }
            D printf("ord: %d\n", ord);
        }
    }
    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);
        D printf("over: %d   ord: %d\n", over, 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];
    }
    D {printarb(root, 0); printf("---------------------------------\n");}
    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);
        D {printarb(root, 0); printf("---------------------------------\n?????????????????????????????\n");}
    }
    bwrite(root);
    return 0;
}