Cod sursa(job #10833)

Utilizator moga_florianFlorian MOGA moga_florian Data 29 ianuarie 2007 18:21:09
Problema Secventa 5 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.91 kb
using namespace std;
#include<fstream>
#include<stdio.h>
#define nmax 1024*1024+5

int a[nmax],v[nmax],c[nmax],poz[nmax],pp[nmax];

int main()
{
FILE *fin=fopen("secv5.in","r"),
     *fout=fopen("secv5.out","w");

int n,p,q;
int i,j,k,aux;


fscanf(fin,"%d%d%d",&n,&p,&q);
for(i=1;i<=n;i++) fscanf(fin,"%d",&a[i]);

//sort
for(i=1;i<=n;i++)
  {
  v[i]=a[i];
  j=i;
  while(j/2&&v[j/2]<v[j])
      {
      aux=v[j/2];
      v[j/2]=v[j];
      v[j]=aux;
      j/=2;                         
      }
  }
i=n;
while(i>1)
 {
 aux=v[1];
 v[1]=v[i];
 v[i]=aux;
 i--;
 
 j=1;
 while(1)
  {
  k=2*j;
  if(k>i) break;
  if(k+1<=i&&v[k+1]>v[k]) k++;
  if(v[j]>v[k]) break;
  
  aux=v[j];
  v[j]=v[k];
  v[k]=aux;
         
  j=k;
  }         
 }

//eliminare distincte
int nn=1;
for(i=2;i<=n;i++)
   if(v[i]!=v[i-1])
      v[++nn]=v[i];   
      
//precalculare pozitii
int li,lf,m;
for(i=1;i<=n;i++)
  {
  li=1;
  lf=nn;
  
  while(1)
   {
   m=(li+lf)/2;
   if(v[m]==a[i])
      break;
   else
   if(v[m]>a[i])
      lf=m-1;
   else
      li=m+1;       
   }         
   
  poz[i]=m;        
  }
 
memset(c,0,sizeof c);
    
//primu punct
int ndist=0;
k=1;
for(i=1;i<=n;i++)
   {
   //bag a[i]
   c[poz[i]]++;
   //verificare
   if(c[poz[i]]==1)
       ndist++;
       
   //mutare primu punct
   while(ndist>q)
     {
     c[poz[k]]--;
     if(c[poz[k]]==0) ndist--;
     k++;    
     }
     
   //retinere
   pp[i]=k;
   }
   
for(i=k;i<=n;i++)
   c[poz[i]]=0;
   
//ultimu punct
k=1;
ndist=0;

int sol=0;

for(i=1;i<=n;i++)
   {
   //bag a[i]
   c[poz[i]]++;
   
   if(c[poz[i]]==1) ndist++;
   
   while(ndist>p-1)
     {
     c[poz[k]]--;
     if(c[poz[k]]==0) ndist--;
     k++;              
     }                
     
   sol+=k-pp[i];
   }
   
fprintf(fout,"%d\n",sol);
    
fclose(fin);
fclose(fout);
return 0;
}