Cod sursa(job #1255875)

Utilizator smallOneAdina Mateescu smallOne Data 5 noiembrie 2014 13:52:19
Problema Schi Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <ctype.h>
#include <cstring>
#include <string>
#include <ctime>
#include <cassert>
#include <utility>

#define LIM 30005

using namespace std;

int A[4 * LIM], pos, val, inceput, sfarsit, v[LIM], ocupied[LIM], n;

void updateARB(int nod, int st, int dr) {
    if(st == dr) {
        A[nod] = 1;
        return;
    }
    int m = (st + dr) / 2;
    if(pos <= m)
        updateARB(2 * nod, st, m);
    else
        updateARB(2 * nod + 1, m + 1, dr);
    A[nod] = A[2 * nod] + A[2 * nod + 1];
}

int queryARB(int nod, int st, int dr) {
    if(inceput <= st && dr <= sfarsit) {
        return A[nod];
    }
    int m = (st + dr) / 2;
    int ocupPos = 0;
    if(m >= inceput)
        ocupPos = queryARB(2 * nod, st, m);
    if(m < sfarsit)
        ocupPos += queryARB(2 * nod + 1, m + 1, dr);
    return ocupPos;
}

// imi cauta a k - a pozitie care e libera din vectorul de ocupati
// in arbore retin ca pe intervalul [a b] am x pozitii ocupate -> ca imi va da b - a - x + 1 ---- pozitii libere =>not cu "lib"
// cu cautare binara caut cea mai din stanga pozitie (cea mai mica pozitie) pentru care lib >= k
int cautBin(int k) {
    int st = 1;
    int dr = n;
    int pos = -1;
    while (st <= dr) {
        int m = (dr + st) / 2;
        inceput = 1;
        sfarsit = m;
        int ocup = queryARB(1, 1, n); // minimul de pozitii ocupate
        int lib = m - 1 - ocup + 1; // b - a - ocup + 1
        if(lib >= k) {
            dr = m - 1;
            pos = m;
        } else if(lib < k) {
            st = m + 1;
        }
    }
    return pos;
}

int main() {
	freopen("schi.in", "r", stdin);
	freopen("schi.out","w", stdout);

    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &v[i]);
    }

    for(int i = n; i > 0; i--) {
        int goodPos = cautBin(v[i]);
        ocupied[goodPos] = i;
        inceput = 1;
        sfarsit = n;
        pos = goodPos;
        updateARB(1, 1, n);
    }

    for(int i = 1; i <= n; i++) {
        printf("%d\n", ocupied[i]);
    }

	return 0;
}