Cod sursa(job #705850)

Utilizator blue_phoenixPosea Elena blue_phoenix Data 5 martie 2012 08:32:43
Problema Secventa 5 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.54 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
#define nmax 1048580
#define MAXIM 1000000
#define MODULO 666013
typedef pair<unsigned,unsigned> pereche;
unsigned int v[nmax],auxiliar[nmax];
unsigned int normalizat[nmax];
vector <pereche> hash[MODULO+1];

char buff[MAXIM+2];
int poz=MAXIM-1;
inline void cit(unsigned &nr){
    while(buff[poz]<'0' || buff[poz]>'9'){//nu e cifra
         poz++;
         if(poz==MAXIM){
           fread(buff,1,MAXIM,stdin);
           poz=0;
         }
   }
   nr=0;
   while(buff[poz]>='0' && buff[poz]<='9'){
        nr=nr*10+buff[poz]-'0';
        poz++;
         if(poz==MAXIM){
           fread(buff,1,MAXIM,stdin);
           poz=0;
         }
   }
}

unsigned n;

long long f(unsigned DIF){//returneaza numarul de subsecvente cu cel mult DIF numere diferite
  unsigned i,j;
  unsigned aux,aux2,aux3;
  unsigned dif=0;
  long long secv=0;
  int inceput=0;
  for(i=0;i<n;i++){
    //incerc sa-l bag in hash
    //daca e nou (nu e deja acolo)
    aux=v[i]%MODULO;
    //aux2=hash[aux].size();
    /*for(j=0;j<aux2;j++){
       if(hash[aux][j].first==v[i]){
           hash[aux][j].second++;
           break;
       }
    }*/
    if(auxiliar[v[i]]==-1){//nu l-am gasit, e nou
       dif++;
       hash[aux].push_back(make_pair(v[i],1));
       auxiliar[v[i]]=hash[aux].size()-1;
       //printf("un nou element,%u\n",v[i]);
    }else{
       hash[aux][auxiliar[v[i]]].second++;
    }
    //
    if(dif<=DIF){
       secv+=i-inceput+1;
       //printf("inceput= %d, final=%d,dif=%d, secv=%lld\n",inceput,i,dif,secv);
    }else{
       //am prea multe diferente
       //trebuie sa tot scot de la inceput
       while(dif>DIF){
         //il scot pe v[inceput] din hash
         //printf("l-am scos pe v[%d]=%u\n",inceput,v[inceput]);
         aux=v[inceput]%MODULO;
         //aux3=hash[aux].size();
         /*for(j=0;j<aux3;j++){
             if(hash[aux][j].first==v[inceput]){
                 hash[aux][j].second--;
                 if(hash[aux][j].second==0){//e singurul de tipul lui
                    hash[aux][j]=hash[aux][aux3-1];
                    hash[aux].pop_back();
                    dif--;
                    //printf("dif=%d\n",dif);
                 }
                break;
             }
         }*/
         //il scot din hash
         aux3=auxiliar[v[inceput]];
         hash[aux][aux3].second--;
         if(hash[aux][aux3].second==0){
           //il scot de tot
           hash[aux][aux3]=hash[aux][hash[aux].size()-1];
           hash[aux].pop_back();
           auxiliar[v[inceput]]=-1;
           dif--;            
         }

         inceput++;
       }
       secv+=i-inceput+1;
    }

  }

  //vectorul auxiliar trebuie resetat pe -1
  for(i=0;i<n;i++)auxiliar[v[i]]=-1;
  //trebuie sa react hashul
  for(i=0;i<MODULO;i++){
      hash[i].clear();   
  }
    //printf("\n***\n");
  return secv;
}

int main(){
  unsigned i;
  unsigned li,ls;
  freopen("secv5.in","r",stdin);
  cit(n);
  cit(li);
  cit(ls);
  long long aux,aux2;
  for(i=0;i<n;i++){
    cit(v[i]);
    auxiliar[i]=v[i];
  }

  sort(auxiliar,auxiliar+n-1);
  int norm=0;
  for (i = 0; i < n; normalizat[auxiliar[i++]] = norm) { // normalizam
    if (i > 0 && auxiliar[i - 1] != auxiliar[i])
       norm += 1;
  }
  //de acum il umplu pe auxiliar cu -1 daca normalizat[v[i]] nu este in hash, indicele unde il gasesc, daca este
  for(i=0;i<n;i++){
    v[i]=normalizat[v[i]];
    auxiliar[v[i]]=-1;
  }

  aux=f(ls);
  aux2=f(li-1);
  FILE *fout=fopen("secv5.out","w");
  fprintf(fout,"%lld\n",aux-aux2);
  //printf("li=%u,%lld\n",li,f(li));
return 0;
}