Cod sursa(job #943597)

Utilizator andreiagAndrei Galusca andreiag Data 25 aprilie 2013 22:03:06
Problema Hotel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.04 kb
#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

const int LEN = (1 << 19);

int A[LEN];
int c = 1;
int N, M;

void update(int);
int find_rightmost(int, int, int, int);
void ins(int, int);
void rem(int, int);
void print_array();




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

    scanf("%d %d", &N, &M);
    while(c < N) c *= 2;
    for(int i = 0; i <= 2*c; i++) A[i] = 0;
    A[c] = N; update(1);

    int a, b, c;
    for(int i = 0; i < M; i++) {
        scanf("%d", &a);
        if (a == 3) printf("%d\n", A[1]);
        else if (a == 1) {scanf("%d %d", &b, &c); ins(b, c);}
        else if (a == 2) {scanf("%d %d", &b, &c); rem(b, c);}
    }

    return 0;
}

void print_array()
{
    for(int i = 0; i <= 2*c; i++)
        printf("%4d", A[i]);
    printf("\n");
}

void update(int pos)
{
    int i = c + pos - 1;
    while(i > 1) {
        i /= 2;
        int x = A[2*i];
        int y = A[2*i + 1];
        if (x > 0 || y > 0) A[i] = (x > y) ? x : y;
        else A[i] = (x < y) ? x : y;
    }
}

int find_rightmost(int pos, int l, int r, int f)
{
    //printf("%d %d %d %d\n", pos, l, r, f);
    if (f < l) return 0;

    int mid = (l + r) / 2;
    if (A[pos] == 0) return 0;
    if (l == r) return l;

    if (f > r) {
        if (A[2*pos + 1] == 0) return find_rightmost(2*pos, l, mid, f);
        else return find_rightmost(2*pos + 1, mid + 1, r, f);
    }
    if (f <= r) {
        int x = find_rightmost(2*pos + 1, mid + 1, r, f);
        if (x) return x;
        else return find_rightmost(2*pos, l, mid, f);
    }
}

void ins(int pos, int n)
{
    if (A[pos + c - 1]) {int m = A[pos + c - 1];
                         if (pos == 1) {
                                if (n < m) {A[pos + c - 1] = -n; update(pos);
                                            A[pos + n + c - 1] = m - n; update(pos + n);}
                                else {A[pos + c - 1] = - n + A[pos + n + c - 1]; update(pos);
                                      A[pos + c + n - 1] = 0; if (pos + n <= c) update(pos + n);}

                        } else {int prev = find_rightmost(1,1,c, pos - 1);
                                int next = pos + m;
                                if (n < m) {A[prev + c - 1] += -n; update(prev);
                                            A[pos + c - 1] = 0; update(pos);
                                            A[pos + n + c - 1] = m - n; update(pos + n);}
                                else {A[prev + c - 1] += -n + A[next + c -1]; update(prev);
                                      A[pos + c - 1] = 0;   update(pos);
                                      A[next + c - 1] = 0;  if (next <= c) update(next);}

                                 }
            }


    else {int prev = find_rightmost(1,1,c,pos); int m = A[prev + c - 1];
          int next = prev + m;
          if (pos + n == next) {A[prev + c - 1] = m - n; update(prev);
                                A[pos + c - 1] = -n + A[next + c - 1]; update(prev);
                                A[next + c - 1] = 0; if (next <= c) update(next);}
          else {A[prev + c - 1] = pos - prev; update(prev);
                A[pos + c - 1] = -n; update(pos);
                A[pos + n + c - 1] = next - pos - n; update(pos + n);}
          }


}

void rem(int pos, int n)
{
    if (A[pos + c - 1]) {int m = -A[pos + c - 1];
                         if (pos == 1) {
                                if (n < m) {A[pos + c - 1] = n; update(pos);
                                            A[pos + n + c - 1] = n - m; update(pos + n);}
                                else {A[pos + c - 1] = n + A[pos + n + c - 1]; update(pos);
                                      A[pos + c + n - 1] = 0; if (pos + n <= c) update(pos + n);}

                        } else {int prev = find_rightmost(1,1,c, pos - 1);

                                int next = pos + m;
                                if (n < m) {A[prev + c - 1] += n; update(prev);
                                            A[pos + c - 1] = 0; update(pos);
                                            A[pos + n + c - 1] = n - m; update(pos + n);}
                                else {A[prev + c - 1] += n + A[next + c -1]; update(prev);
                                      A[pos + c - 1] = 0;   update(pos);
                                      A[next + c - 1] = 0;  if (next <= c) update(next);}

                                 }
            }


    else {int prev = find_rightmost(1,1,c,pos); int m = -A[prev + c - 1];
          int next = prev + m;
          if (pos + n == next) {A[prev + c - 1] = n - m; update(prev);
                                A[pos + c - 1] = n + A[next + c - 1]; update(prev);
                                A[next + c - 1] = 0; if (next <= c) update(next);}
          else {A[prev + c - 1] = prev - pos; update(prev);
                A[pos + c - 1] = n; update(pos);
                A[pos + n + c - 1] = pos + n - next; update(pos + n);}
     }

}