Cod sursa(job #14719)

Utilizator astronomyAirinei Adrian astronomy Data 9 februarie 2007 16:03:19
Problema Hotel Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.43 kb
#include <stdio.h>

#define MAXN (1 << 17)
#define MAXARB (1 << 18)
#define left (nod << 1)
#define right ((nod << 1) | 1)
#define mid ((st+dr) >> 1)
#define max(a,b) ((a) > (b) ? (a) : (b))

int N, P, L[MAXARB], R[MAXARB], Max[MAXARB], Nr[MAXARB];
int arb[MAXARB], sum[MAXARB];

int a, b, val;

void update(int nod, int st, int dr, int tsum)
{
    int lst, ldr, rst, rdr, mst, mdr;

    lst = ldr = rst = rdr = mst = mdr = 0;
    
    if(a <= st && dr <= b)
    {
        sum[nod] += val, arb[nod] += Nr[nod]*val;
        if(val == 1) // am bagat
            L[nod] = R[nod] = Max[nod] = Nr[nod];
        else // am scos
            L[nod] = R[nod] = Max[nod] = 0;
    }
    else
    {
        if(a <= mid) update(left, st, mid, tsum+sum[nod]);
        if(b > mid) update(right, mid+1, dr, tsum+sum[nod]);
        arb[nod] = arb[left]+arb[right]+sum[nod]*Nr[nod];

        if(arb[left]+(tsum+sum[nod])*Nr[left] > 0)
            lst = L[left], rst = R[left], mst = Max[left];
        if(arb[left]+(tsum+sum[nod])*Nr[left] == Nr[left])
            lst = rst = mst = Nr[left];
        if(arb[right]+(tsum+sum[nod])*Nr[right] > 0)
            ldr = L[right], rdr = R[right], mdr = Max[right];
        if(arb[right]+(tsum+sum[nod])*Nr[right] == Nr[right])
            ldr = rdr = mdr = Nr[right];
            
        Max[nod] = max(mst, mdr), Max[nod] = max(Max[nod], rst+ldr);
        L[nod] = (lst == Nr[left] ? lst+ldr : lst);
        R[nod] = (rdr == Nr[right] ? rdr+rst : rdr);
    }
}

void init(int nod, int st, int dr)
{
    Nr[nod] = dr-st+1;
    if(st == dr)
        return ;
    init(left, st, mid), init(right, mid+1, dr);
}

int main(void)
{
    freopen("hotel.in", "rt", stdin);
    freopen("hotel.out", "wt", stdout);

    int i, t, j, k, cnt = 0;

    scanf("%d %d\n", &N, &P);

    init(1, 1, N);
    
    for(i = 1; i <= N; i++)
        a = b = i, val = 1, update(1, 1, N, 0);
        
    for(i = 1; i <= P; i++)
    {
        scanf("%d ", &t);
        if(t == 1)
        {
            scanf("%d %d\n", &j, &k), a = j, b = j+k-1;
            val = -1;
            update(1, 1, N, 0);
        }
        if(t == 2)
        {
            scanf("%d %d\n", &j, &k), a = j, b = j+k-1;
            val = 1;
            update(1, 1, N, 0);
        }
        if(t == 3)
        {
            cnt++;
            printf("%d\n", Max[1]);
        }
    }

    return 0;
}