Cod sursa(job #2497304)

Utilizator marinaoprOprea Marina marinaopr Data 22 noiembrie 2019 13:08:50
Problema Zeap Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.04 kb
    #include <stdio.h>
#include <iostream>
#include <algorithm>

#define NMAX 300005

#define INF 1000000001

using namespace std;

FILE *fin = fopen("zeap.in", "r");
FILE *fout = fopen("zeap.out", "w");

struct arbore {int mini; int maxi; int diff;} aint[4*NMAX];
struct query {int val; int time; int tip; int poz;} q[NMAX];

int n,capat,i;
char sir[21];

int get_number(int i)
{
    int nr = 0;
    while(sir[i]>='0' and sir[i]<='9')
        nr = nr*10 + (sir[i++]-'0');

    return nr;
}

bool cmp1(query a,query b)
{
    if(a.tip > 2 and b.tip > 2)
        return (a.val < b.val);
    if(a.tip > 2)
        return 0;
    if(b.tip > 2)
        return 1;

    return (a.val < b.val or (a.val == b.val and a.time<b.time));
}

bool cmp2(query a, query b)
{
    return (a.time < b.time);
}

void build(int nod, int low, int high)
{
    aint[nod].maxi = -INF;
    aint[nod].mini = aint[nod].diff = INF;

    if(low == high)
        return;

    int mid = (low+high) /2;
    build(2*nod,low,mid);
    build(2*nod+1,mid+1,high);
}

void update(int nod, int low, int high, int poz, int val)
{
    if(low == high)
    {
        if(val)
            aint[nod].maxi = aint[nod].mini = val;
        else
        {
            aint[nod].maxi = -INF;
            aint[nod].mini = INF;
        }

        return;
    }

    int mid = (low+high) /2;
    if(poz <= mid)
        update(2*nod, low, mid, poz, val);
    else
        update(2*nod+1, mid+1, high, poz, val);

    aint[nod].maxi = max(aint[2*nod].maxi, aint[2*nod+1].maxi);
    aint[nod].mini = min(aint[2*nod].mini, aint[2*nod+1].mini);
    aint[nod].diff = min( min(aint[2*nod].diff, aint[2*nod+1].diff), aint[2*nod+1].mini-aint[2*nod].maxi);
}

int query(int nod, int low, int high, int index)
{
    if(low == high)
        if(aint[nod].maxi == -INF)
            return 0;
        else
            return 1;

    int mid = (low+high) /2;
    if(index <= mid)
        return query(2*nod, low, mid, index);
    else
        return query(2*nod+1, mid+1, high, index);
}

int main()
{
    while(fgets(sir, 20, fin))
    {
        ++n;

        if(sir[0] == 'I')
        {
            q[n].val = get_number(2);
            q[n].tip = 0;
        }
        else
            if(sir[0] == 'S')
            {
                q[n].val = get_number(2);
                q[n].tip = 1;
            }
            else
                if(sir[0] == 'C')
                {
                    q[n].val = get_number(2);
                    q[n].tip = 2;
                }
                else
                    if(sir[1] == 'A')
                        q[n].tip = 3;
                    else
                        q[n].tip = 4;

       q[n].time = n;
    }

    sort(q+1, q+n+1, cmp1);
    q[0].val = -INF;
    for(i=1; i<=n and q[i].tip<=2; ++i)
    {
        if(q[i].val > q[i-1].val)
            q[i].poz = 1+q[i-1].poz;
        else
            q[i].poz = q[i-1].poz;

        capat = max(capat, q[i].poz);
    }

    build(1,1,capat);

    sort(q+1, q+n+1, cmp2);
    for(i=1; i<=n; ++i)
        if(q[i].tip == 0)
            update(1,1,capat,q[i].poz,q[i].val);
        else
            if(q[i].tip == 1)
                if(!query(1,1,capat,q[i].poz))
                    fprintf(fout, "-1\n");
                else
                    update(1,1,capat,q[i].poz,0);
            else
                if(q[i].tip == 2)
                    fprintf(fout, "%d\n", query(1,1,capat,q[i].poz));
                else
                    if(q[i].tip == 3)
                        if(aint[1].maxi == -INF)
                            fprintf(fout, "-1\n");
                        else
                            fprintf(fout, "%d\n", aint[1].maxi-aint[1].mini);
                    else
                        if(aint[1].maxi == -INF)
                            fprintf(fout, "-1\n");
                        else
                            fprintf(fout, "%d\n", aint[1].diff);

    fclose(fin);
    fclose(fout);
    return 0;
}