Pagini recente » Cod sursa (job #1291557) | Cod sursa (job #2640156) | Cod sursa (job #2870466) | Cod sursa (job #3178740) | Cod sursa (job #705949)
Cod sursa(job #705949)
#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;
}