Cod sursa(job #705746)

Utilizator blue_phoenixPosea Elena blue_phoenix Data 4 martie 2012 21:23:48
Problema Secventa 5 Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <stdio.h>
#include <vector>
using namespace std;
#define nmax 1048580
#define MAXIM 1000000
#define MODULO 666013
typedef pair<unsigned,unsigned> pereche;
unsigned int v[nmax];
vector <pereche> hash[MODULO+1];

char buff[MAXIM+2];
int poz=MAXIM-1;
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(j==aux2){//nu l-am gasit, e nou
       dif++;
       hash[aux].push_back(make_pair(v[i],1));
       //printf("un nou element,%u\n",v[i]);
    }
    //
    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];
                    hash[aux].pop_back();
                    dif--;
                    //printf("dif=%d\n",dif);
                 }
                break;
             }
         }
         inceput++;
       }
       secv+=i-inceput+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]);
  }

  aux=f(ls);
  aux2=f(li-1);
  //printf("secv=%lld-%lld=%lld\n",aux,aux2,aux-aux2);//f(x)=numarul de subsecv cu un numar de diferente mai mic sau egal cu x
  FILE *fout=fopen("secv5.out","w");
  fprintf(fout,"%lld\n",aux-aux2);
  //printf("li=%u,%lld\n",li,f(li));
return 0;
}