Cod sursa(job #2954007)

Utilizator Giulian617Buzatu Giulian Giulian617 Data 12 decembrie 2022 23:08:34
Problema Hotel Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("hotel.in");
ofstream g("hotel.out");
const int NMAX=100005;
int n,Q,op,add,start,finish,val;
struct
{
    int best,max_left,max_right,lazy=1;///best represents the longest sequence of ones
    ///max_left represents the longest prefix of ones
    ///max_right represents the longest suffix of ones
    ///lazy represents the value on our nodes,hence we start with all elements to 1 and invert the logic of the operations
} Tree[4*NMAX];
void update(int node,int left,int right)
{
    ///first we propagate
    if(Tree[node].lazy==-1)///we set the whole segment to 0
    {
        Tree[node].lazy=0;
        Tree[2*node].lazy=-1;
        Tree[2*node+1].lazy=-1;
    }
    else if(Tree[node].lazy==1)///we set the whole segment to 1
    {
        Tree[2*node].lazy=1;
        Tree[2*node+1].lazy=1;
    }
    if(val==-1)
        Tree[node].lazy=0;
    if(start<=left && right<=finish)
    {
        Tree[node].lazy=val;
        return;
    }
    int middle=(left+right)/2;
    if(start<=middle)
        update(2*node,left,middle);///update left son
    if(middle<finish)
        update(2*node+1,middle+1,right);///update right son
}
void query(int node,int left,int right)
{
    ///first we propagate
    if(Tree[node].lazy==1)///we "set" the whole segment to 1
    {
        Tree[node].best=right-left+1;
        Tree[node].max_left=right-left+1;
        Tree[node].max_right=right-left+1;
    }
    else if(Tree[node].lazy==-1)///we "set" the whole segment to 0
    {
        Tree[node].best=0;
        Tree[node].max_left=0;
        Tree[node].max_right=0;
    }
    if(left==right)
        return;
    int middle=(left+right)/2;
    query(2*node,left,middle);///query left son
    query(2*node+1,middle+1,right);///query right son
    Tree[node].max_left=Tree[2*node].max_left;
    if(Tree[2*node].max_left==middle-left+1)///the max_left for the left son is the full segment
        Tree[node].max_left+=Tree[2*node+1].max_left;///so we can add to it the max_left for the right son
    Tree[node].max_right=Tree[2*node+1].max_right;
    if(Tree[2*node+1].max_right==right-(middle+1)+1)///the max_right for the right son is the full segment
        Tree[node].max_right+=Tree[2*node].max_right;///so we can add to it the max_right for the left son
    Tree[node].best=max({Tree[2*node].best,Tree[2*node+1].best,Tree[2*node].max_right+Tree[2*node+1].max_left});///the new best is either the best on the left son, the best on the right son
    ///or a combination of max_right of the left son and max_left of the right son
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    f>>n>>Q;
    for(int q=1; q<=Q; q++)
    {
        f>>op;
        if(op==1)
        {
            f>>start>>add;
            finish=start+add-1;
            val=-1;
            update(1,1,n);
        }
        else if(op==2)
        {
            f>>start>>add;
            finish=start+add-1;
            val=1;
            update(1,1,n);
        }
        else
        {
            query(1,1,n);
            g<<Tree[1].best<<'\n';
        }
    }
    return 0;
}