Cod sursa(job #705949)

Utilizator blue_phoenixPosea Elena blue_phoenix Data 5 martie 2012 11:20:12
Problema Secventa 5 Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
#define nmax 1048580
#define MAXIM 1000000
#define MODULO 666013
typedef pair<unsigned,unsigned> pereche;
unsigned int v[nmax];
char locatie[nmax];
vector <pereche> auxiliar;
vector <unsigned int> 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++){
    //il bag in hash; daca e nou, nu era inainte, dif++
    aux=v[i]%MODULO;
    
    if(locatie[v[i]]==0){//nu era in hash
       dif++;
    }
    hash[aux].push_back(v[i]);
    locatie[v[i]]=1;

    if(dif<=DIF){
       secv+=i-inceput+1;
    }else{
       //am prea multe diferente
       //trebuie sa tot scot de la inceput
       int ok;
       while(dif>DIF){
         //il scot pe v[inceput] din hash; sigur apare acolo, nu mai verific
         aux=v[inceput]%MODULO;
         aux2=hash[aux].size();
         ok=0;//presupun ca apare doar odata
         for(j=0;j<aux2;j++){
            if(hash[aux][j]==v[inceput]){
              aux3=j;
              break;
            }
         }
         for(j++;j<aux2;j++)
            if(hash[aux][j]==v[inceput]){
               ok=1;
               break;
            }

         if(ok==0){//daca a aparut doar odata
           //il scot de tot
           locatie[v[inceput]]=0;
           dif--;            
         }
         aux2=hash[aux].size()-1;
         hash[aux][aux3]=hash[aux][aux2];
         hash[aux].pop_back();
         inceput++;
       }
       secv+=i-inceput+1;
    }

  }

  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.push_back(make_pair(v[i],i));
  }

  sort(auxiliar.begin(),auxiliar.end());
  int norm=0;
  for (i = 0; i < n; v[auxiliar[i++].second] = norm) { // normalizam
    if (i > 0 && auxiliar[i - 1].first != auxiliar[i].first){
       norm += 1;
    }
  }
  //de acum il umplu pe locatie[v[i]] cu 0 daca v[i] nu este in hash, 1 daca este (2^20 / 666013 <2 :| )
  memset(locatie,0,sizeof(locatie));
  aux=f(ls);
  memset(locatie,0,sizeof(locatie));
  //trebuie sa react hashul
  for(i=0;i<MODULO;i++){
      hash[i].clear();   
  }

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