Cod sursa(job #949423)

Utilizator costinbanuCostin Banu costinbanu Data 13 mai 2013 18:56:27
Problema Hotel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.99 kb
#include<cstdio>
#include<vector>
using namespace std;

struct INTE{
    int a, b, oc, po; //in int. [a,b] cate sunt OCupate si care e PrimaOcupata
    bool os, od;
};

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

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

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

int query_i(int poz, int x, int y){pasi++;
    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){pasi++;
    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;
}

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;
    }
}

int lung(int poz){pasi++;
    INTE tata = c[poz], st = c[2*poz], dr = c[2*poz+1];
        if (tata.oc > 0) return maxi((tata.po - tata.a + 2), (tata.b - tata.po - tata.oc - 1));
        else {
            if (tata.od == 0 && tata.os == 1) return dr.b - dr.a + 1 + lung(poz*2);
            else {
                if (tata.od == 1 && tata.os == 0) return st.b - st.a + 1 + lung(poz*2+1);
                else {
                    if (tata.od == 1 && tata.os == 1) return maxi(lung(poz*2), lung(poz*2+1));
                    else return tata.b - tata.a + 1;
                }
            }

        }
}

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 = 0; i < p; i++){
            fscanf (in, "%d", &ctrl);
            pasi=0;
            if (ctrl == 3) fprintf(out, "%d\n", lung(1));
            else {
                fscanf(in, "%d %d", &x, &y);
                if (ctrl == 1) ins(x, y);
                else if (ctrl == 2) del(x, y);
            }
        }
        fclose(in), fclose(out);
    }
    return 0;
}