Cod sursa(job #1821349)

Utilizator andrei_diaconu11Andrei C. Diaconu andrei_diaconu11 Data 2 decembrie 2016 22:47:28
Problema Hotel Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <stdio.h>
#include <ctype.h>
#define LIM1 400000
#define LIM 1<<17
struct lp{
  int suf, pref, lmax;
  void setvalue(int val){
    suf=pref=lmax=val;
  }
} arb[LIM1];
FILE *fi, *fo;
char BUF[LIM], BUF2[LIM];
int poz, poz2;

inline char getChar(){
  poz++;
  if(poz>=LIM){
    fread(BUF,LIM,1,fi);
    poz=0;
  }
  return BUF[poz];
}

inline int getNr(){
  int r=0, semn=1;
  char ch=getChar();
  while(isdigit(ch)==0 && ch!='-') ch=getChar();
  if(ch=='-'){
    semn=-1;
    ch=getChar();
  }
  while(isdigit(ch)!=0){
    r=r*10+semn*(ch-'0');
    ch=getChar();
  }
  return r;
}

inline void putch(char ch){
  BUF2[poz2++]=ch;
  if(poz2==LIM){
    fwrite(BUF2,LIM,1,fo);
    poz2=0;
  }
}

inline void baga(int x){
  char s[15];
  int k=0;
  if(x<0){
    putch('0');
    return;
  }
  do{
    s[k++]=x%10+'0';
    x/=10;
  }while(x);
  while(k>0){
    k--;
    putch(s[k]);
  }
}

int lazy[2*LIM1];//-1 daca tre sa fie goale, 1 daca tre sa fie ocupate
void build_arb(int nod, int st, int dr){
  int div=(st+dr)/2;
  arb[nod].setvalue(dr-st+1);
  if(st!=dr){
    build_arb(2*nod,st,div);
    build_arb(2*nod+1,div+1,dr);
  }
}

inline int maxim(int a, int b){
  return a>b ? a:b;
}

inline void Back_To_Work(int nod, int st, int dr){
  if(lazy[nod]==1)
    arb[nod].setvalue(0);
  if(lazy[nod]==-1)
    arb[nod].setvalue(dr-st+1);
  if(lazy[nod]!=0)
    lazy[2*nod]=lazy[2*nod+1]=lazy[nod];
  lazy[nod]=0;
}

inline void calc(int nod, int st, int dr){
  arb[nod].lmax=maxim(maxim(arb[2*nod].lmax,arb[2*nod+1].lmax),arb[2*nod].suf+arb[2*nod+1].pref);
  int div=(st+dr)/2;
  Back_To_Work(2*nod,st,div);
  Back_To_Work(2*nod+1,div+1,dr);
  arb[nod].pref=arb[2*nod].pref;
  if(arb[2*nod].lmax==div-st+1)
    arb[nod].pref+=arb[2*nod+1].pref;
  arb[nod].suf=arb[2*nod+1].suf;
  if(arb[2*nod+1].lmax==dr-div)
    arb[nod].suf+=arb[2*nod].suf;
}

void update(int nod, int st, int dr, int a, int b, int val){
  Back_To_Work(nod,st,dr);
  if(a<=st && dr<=b){
    lazy[nod]=val;
    Back_To_Work(nod,st,dr);
    return;
  }
  int div=(st+dr)/2;
  if(a<=div)
    update(2*nod,st,div,a,b,val);
  if(b>div)
    update(2*nod+1,div+1,dr,a,b,val);
  calc(nod,st,dr);
}

int main()
{
  int n, m, op, dr, st;
  fi=fopen("hotel.in", "r");
  fo=fopen("hotel.out", "w");
  n=getNr();
  m=getNr();
  build_arb(1,1,n);
  for(m--;m>=0;m--){
    op=getNr();
    if(op==3){
      baga(arb[1].lmax);
      putch('\n');
    }
    else{
      st=getNr();
      dr=getNr();
      dr=st+dr-1;
      if(op==1)
        update(1,1,n,st,dr,1);
      if(op==2)
        update(1,1,n,st,dr,-1);
    }
  }
  fclose(fi);
  if(poz2>0)
    fwrite(BUF2,poz2,1,fo);
  fclose(fo);
  return 0;
}