Cod sursa(job #2231597)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 15 august 2018 01:36:08
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <bits/stdc++.h>

#define MaxN 100005
#define MaxP 200005

#define LeftSon 2*Pos
#define RightSon 2*Pos + 1

std::ifstream InFile("hotel.in");
std::ofstream OutFile("hotel.out");

int max(int x1, int x2, int x3) {
    return std::max(std::max(x1, x2), x3);
}

int N, P;

int Lazy[4*MaxN+5];
int MaxLeft[4*MaxN+5], MaxMiddle[4*MaxN+5], MaxRight[4*MaxN+5];

void BuildTree(int Left = 1, int Right = N, int Pos = 1) {
    MaxLeft[Pos] = MaxRight[Pos] = MaxMiddle[Pos] = Right-Left + 1;
    if(Left == Right) {
        return;
    }

    int Middle = (Left+Right)/2;
    BuildTree(Left, Middle, LeftSon);
    BuildTree(Middle+1, Right, RightSon);
}


void Propagation(int Left = 1, int Right = N, int Pos = 1) {
    if(Lazy[Pos] == 2) {
        MaxLeft[Pos] = MaxRight[Pos] = MaxMiddle[Pos] = Right-Left + 1;

        if(Left != Right)
            Lazy[LeftSon] = Lazy[RightSon] = Lazy[Pos];
    } else
    if(Lazy[Pos] == 1) {
        MaxLeft[Pos] = MaxRight[Pos] = MaxMiddle[Pos] = 0;

        if(Left != Right)
            Lazy[LeftSon] = Lazy[RightSon] = Lazy[Pos];
    }

    Lazy[Pos] = 0;
}

void Update(int A, int B, int UpdateValue, int Left = 1, int Right = N, int Pos = 1) {
    if(A <= Left && Right <= B) {
        Lazy[Pos] = UpdateValue;
        Propagation(Left, Right, Pos);
        return;
    }

    Propagation(Left, Right, Pos);
    int Middle = (Left+Right)/2;

    if(A <= Middle) {
        Update(A, B, UpdateValue, Left, Middle, LeftSon);
    }
    else {
        Propagation(Left, Middle, LeftSon);
    }

    if(Middle < B) {
        Update(A, B, UpdateValue, Middle+1, Right, RightSon);
    }
    else {
        Propagation(Middle+1, Right, RightSon);
    }

    MaxMiddle[Pos] = max(MaxMiddle[LeftSon], MaxMiddle[RightSon], MaxRight[LeftSon] + MaxLeft[RightSon]);
    MaxLeft[Pos] = MaxLeft[LeftSon];
    MaxRight[Pos] = MaxRight[RightSon];

    if(MaxLeft[Pos] == Middle-Left+1) MaxLeft[Pos] += MaxLeft[RightSon];
    if(MaxRight[Pos] == Right-Middle) MaxRight[Pos] += MaxRight[LeftSon];
}


void Citire() {
    InFile >> N >> P;
}

int Pos, M;

void Query1() {
    InFile >> Pos >> M;
    Update(Pos, Pos+M-1, 1);
}
void Query2() {
    InFile >> Pos >> M;
    Update(Pos, Pos+M-1, 2);
}
void Query3() {
    Propagation();
    OutFile << MaxMiddle[1] << '\n';
}

typedef void (*void_ptr)();

void Rezolvare() {
    BuildTree();

    void_ptr Query[3];
    Query[0] = &Query1;
    Query[1] = &Query2;
    Query[2] = &Query3;

    for (int i=0, Type; i<P; i++) {
        InFile >> Type;

        // Because I can lolz
        (*Query[Type-1])();
    }
}

int main()
{
    Citire();
    Rezolvare();

    return 0;
}