Cod sursa(job #1274580)

Utilizator buzu.tudor67Tudor Buzu buzu.tudor67 Data 23 noiembrie 2014 23:46:46
Problema Heapuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.88 kb
#include<cstdio>
#include<cassert>
#include<vector>
using namespace std;
 
const int MAX_N = 100005;
const int MODULO = 66013;
  
vector < pair<int,int> > h[MODULO];
int i,j,n,x,sol,maxglobal;
int aparitii,blocuri,surplus;
 
class Min_Heap{
      private:
              int h[100005];
              int heapsize;
              void coboara(int k);
              void urca(int k);
      public:
             Min_Heap();
             void adauga(int k);
             void sterge(int k);
             int minim();
             int heap_size();
};
  
void Min_Heap::coboara(int k){
     bool ok=1;
     int nod;
  
     while(ok)
     {
      ok=0;
        
      if(2*k<=heapsize){
                        nod=2*k;
                          
                        if(2*k+1<=heapsize && h[2*k+1]<h[nod]) nod=2*k+1;
                          
                        if(h[nod]<h[k]){
                                        ok=1;
                                        swap(h[nod],h[k]);
                                        k=nod;
                                       }
                       }
     }
}
  
void Min_Heap::urca(int k){
     while(k>1 && h[k]<h[k>>1]){
                                swap(h[k],h[k/2]);
                                k>>=1;
                               }
}
  
Min_Heap::Min_Heap(){
     heapsize=0;
}
  
void Min_Heap::adauga(int x){
     h[++heapsize]=x;
     urca(heapsize);
}
  
void Min_Heap::sterge(int k){
     h[k]=h[heapsize--];
     urca(k);
     coboara(k);
}
  
int Min_Heap::minim(){
    return h[1];
}
  
int Min_Heap::heap_size(){
    return heapsize;
}
  
int este(const int &x){
    int zona=x%MODULO;
      
    for(unsigned int j=0;j<h[zona].size();j++)
      if(h[zona][j].first==x) return h[zona][j].second;
        
    return 0;
}
  
void adauga(const int &x, const int &nr){
     int zona=x%MODULO;
       
     if(!este(x)) h[zona].push_back(make_pair(x,nr));
     else{
          for(unsigned int j=0;j<h[zona].size();j++)
           if(h[zona][j].first==x){
                                   h[zona][j].second+=nr;
                                   return;
                                  }
         }
}
  
void sterge(const int &x, const int &nr){
     int zona=x%MODULO;
        
     for(unsigned int j=0;j<h[zona].size();j++)
       if(h[zona][j].first==x){
                               h[zona][j].second-=nr;
                               if(h[zona][j].second==0){
                                                        h[zona][j]=h[zona].back();
                                                        h[zona].pop_back();              
                                                       }
                               return;
                              }
}
 
Min_Heap pq;
  
int main(){
    assert(freopen("patrate6.in","r",stdin));
    assert(freopen("patrate6.out","w",stdout));
    assert(scanf("%d",&n)==1);
    for(i=1;i<=n;i++){
                      assert(scanf("%d",&x)==1);
                      if(!este(x))pq.adauga(x);
                      adauga(x,1);
                      if(x>maxglobal) maxglobal=x;
                     }
  
    while(pq.heap_size())
         {
          x=pq.minim();
          pq.sterge(1); 
  
          if(x>sol) sol=x;
          
          aparitii=este(x);
          blocuri=aparitii/4; 
          
          sterge(x,este(x));
          
          if(blocuri>=1){ 
                         if(!este(x+1)) pq.adauga(x+1);
                         adauga(x+1,blocuri);
                         if(x+1>maxglobal) maxglobal=x+1;
                        }
          
          if(pq.heap_size() && aparitii%4) surplus=1;
          if(!pq.heap_size() && aparitii%4>1) surplus=1;
         } 
      
    printf("%d",sol+surplus);
      
    fclose(stdin);
    fclose(stdout);
    return 0;
}