Cod sursa(job #951308)

Utilizator costinbanuCostin Banu costinbanu Data 20 mai 2013 08:38:09
Problema Hotel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.1 kb
#include<cstdio>
#include<vector>
using namespace std;

struct INTE{
    int a, b, oc, po, no; //[a,b], ocupate, prima ocupata, max(neocupate)
    bool os, od;
};

vector <INTE> c(2);
int n, p, ctrl, x, y, l;

inline int maxi(int a, int b) { return (a > b) ? a : b; }

void build(int a, int b, int poz){
    c[poz].a = a;
    c[poz].b = b;
    c[poz].oc = c[poz].po = c[poz].os = c[poz].od = 0;
    if (a < b-2){
        c.resize(2*poz+2);
        build(a, (a+b)/2, 2*poz);
        build((a+b)/2+1, b, 2*poz+1);
    }
}

void update_sus(int poz){
    if (poz > 1){//l++;
        INTE *tata = &c[poz/2], *st = &c[(poz/2)*2], *dr = &c[(poz/2)*2+1];
        if (st->oc > 0 && dr->oc > 0){
            int stanga = (st->po - st->a),
                mijloc = (st->b - st->po - st->oc + 1) + (dr->po - dr->a),
                dreapta = (dr->b - dr->po - dr->oc + 1);
            st->no = maxi(stanga, (st->b - st->po - st->oc + 1));
            dr->no = maxi(dreapta, dr->po - dr->a);
            tata->no = maxi(maxi(stanga, mijloc), dreapta);
        }
        else if (st->oc > 0 && dr->oc == 0){
            int stanga = (st->po - st->a),
                mijloc = (st->b - st->po - st->oc + 1) + (dr->b - dr->a + 1),
                dreapta = (dr->b - dr->a + 1);
            st->no = maxi(stanga, (st->b - st->po - st->oc + 1));
            dr->no = dr->b - dr->a + 1;
            tata->no = maxi(maxi(stanga, mijloc), dreapta);
        }
        else if (st->oc == 0 && dr->oc > 0){
            int stanga = (st->b - st->a + 1),
                mijloc = (st->b - st->a + 1) + (dr->po - dr->a),
                dreapta = (dr->b - dr->po - dr->oc + 1);
            st->no = st->b - st->a + 1;
            dr->no = maxi(dreapta, dr->po - dr->a);
            tata->no = maxi(maxi(stanga, mijloc), dreapta);
        }
        update_sus(poz/2);
    }
}

int query_i(int poz, int x, int y){//l++;
    if (x >= c[poz].a && x+y-1 <= c[poz].b && y >= (c[poz].b - c[poz].a + 1)/2) return poz;
    else {
        if (x >= c[poz].a && x+y-1 <= (c[poz].a + c[poz].b) / 2) {
            //c[poz].os = 1;
            return query_i(2*poz, x, y);
        }
        else if (x >= (c[poz].a + c[poz].b) / 2 + 1 && x+y-1 <= c[poz].b) {
            //c[poz].od = 1;
            return query_i(2*poz+1, x, y);
        }
        else return -1;
    }
}

int query_d(int poz, int x, int y){//l++;
    if (x >= c[poz].a && x+y-1 <= c[poz].b && x <= c[poz].po + c[poz].oc) return poz;
    else {
        if (x >= c[poz].a && x+y-1 <= (c[poz].a + c[poz].b) / 2) return query_d(2*poz, x, y);
        else if (x >= (c[poz].a + c[poz].b) / 2 + 1 && x+y-1 <= c[poz].b) return query_d(2*poz+1, x, y);
        else return -1;
    }
}

void ins(int cam, int cati){
    int poz = query_i(1, cam, cati);
    if (poz != -1) c[poz].oc += cati, c[poz].po = cam;
    update_sus(poz);
}

void del(int cam, int cati){
    int poz = query_d(1, cam, cati);
    if (poz != -1) {
        c[poz].oc -= cati;
        if (c[poz].oc == 0) {
            c[poz].po = 0;
            if (poz % 2 == 0) c[poz/2].os = 0;
            else c[poz/2].od = 0;
        }
        else c[poz].po += cati;
    }
    update_sus(poz);
}

int main(){
    FILE *in = fopen("hotel.in", "r"), *out = fopen("hotel.out", "w");
    if (in && out) {
        fscanf(in, "%d %d\n", &n, &p);
        build(1, n, 1);
        //for(int i = 1; i < c.size(); i++) printf("[%d %d]: ocupate: %d prima: %d\n", c[i].a, c[i].b, c[i].oc, c[i].po);
        for(int i = 0; i < p; i++){
            fscanf (in, "%d", &ctrl);
            //l=0;
            if (ctrl == 3) fprintf(out, "%d\n", (c[1].no == 0) ? n : c[1].no);
            else {
                fscanf(in, "%d %d", &x, &y);
                if (ctrl == 1) ins(x, y);
                else if (ctrl == 2) del(x, y);
            }

            //printf("operatia %d in %d pasi\n",ctrl, l);
            //for(int i = 1; i < c.size(); i++) printf("[%d %d]: ocupate: %d prima: %d max_neocupate:%d\n", c[i].a, c[i].b, c[i].oc, c[i].po, c[i].no);
        }
        fclose(in), fclose(out);
    }
    return 0;
}