Cod sursa(job #13543)

Utilizator stef2nStefan Istrate stef2n Data 6 februarie 2007 23:09:39
Problema Secventa 5 Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.29 kb
#include <stdio.h>

#define infile "secv5.in"
#define outfile "secv5.out"
#define NMAX 1050000
#define MOD 666013
struct NOD{unsigned int val,count;};

FILE *fin,*fout;
int n,L,U;
unsigned int x[NMAX];
NOD hash[MOD+2][4];
int hashcnt[MOD+2];
int poz1[NMAX],poz2[NMAX];

void citire()
  {
   int i,j;
   char sir[13];
   fin=fopen(infile,"r");
   fscanf(fin,"%d %d %d\n",&n,&L,&U);
   for(i=0;i<n;i++)
      {
       fgets(sir,13,fin);
       j=0;
       x[i]=0;
       while(sir[j]>='0')
           {
            x[i]=x[i]*10+(sir[j]-'0');
            j++;
           };
      }
   fclose(fin);
  }

inline void adauga(unsigned int x)
  {
   int i,poz=x%MOD;
   for(i=0;i<hashcnt[poz];i++)
      if(hash[poz][i].val==x)
        {
         hash[poz][i].count++;
         return;
        }
   NOD b;
   b.val=x;
   b.count=1;
   hash[poz][hashcnt[poz]++]=b;
  }

inline void sterge(unsigned int x)
  {
   int i,poz=x%MOD;
   for(i=0;i<hashcnt[poz];i++)
      if(hash[poz][i].val==x)
        {
         if(hash[poz][i].count==1)
           hash[poz][i]=hash[poz][hashcnt[poz]--];
         else
           hash[poz][i].count--;
         return;
        }
  }

inline NOD *cauta(unsigned int x)
  {
   int i,poz=x%MOD;
   for(i=0;i<hashcnt[poz];i++)
      if(hash[poz][i].val==x)
        return &hash[poz][i];
   return NULL;
  }

void solve1(int *poz, int DIM)
  {
   int i,lung=0,ind=-1,stop=0;
   NOD *b;
   for(i=0;i<MOD;i++)
      hashcnt[i]=0;
   for(i=0;i<n;i++)
      {
       if(!cauta(x[i]))
         lung++;
       adauga(x[i]);
       if(lung==DIM)
         {
          if(ind==-1)
            ind++;
          stop=0;
          do{
             b=cauta(x[ind]);
             if(b->count==1)
               stop=1;
             else
               sterge(x[ind++]);
            }while(!stop);
         }
       else
         if(lung>DIM)
           {
            stop=0;
            do{
               b=cauta(x[ind]);
               if(b->count==1)
                 {
                  lung--;
                  stop=1;
                 }
               sterge(x[ind++]);
              }while(!stop);

            stop=0;
            do{
               b=cauta(x[ind]);
               if(b->count==1)
                 stop=1;
               else
                 sterge(x[ind++]);
              }while(!stop);
           }
       poz[i]=ind;
      }
  }

void solve2(int *poz, int DIM)
  {
   int i,lung=0,ind=-1,stop=0;
   NOD *b;
   for(i=0;i<MOD;i++)
      hashcnt[i]=0;
   for(i=0;i<n;i++)
      {
       if(!cauta(x[i]))
         lung++;
       adauga(x[i]);
       if(lung==DIM)
         {
          if(ind==-1)
            ind=0;
         }
       else
         if(lung>DIM)
           {
            stop=0;
            do{
               b=cauta(x[ind]);
               if(b->count==1)
                 {
                  lung--;
                  stop=1;
                 }
               sterge(x[ind++]);
              }while(!stop);
           }
       poz[i]=ind;
      }
  }


int main()
{
int i;
long long count=0;
citire();
solve1(poz1,L);// cea mai scurta secventa de L nr distincte
solve2(poz2,U);// cea mai lunga secventa de U nr distincte
for(i=0;i<n;i++)
   if(poz1[i]!=-1)
     if(poz2[i]==-1)
       count+=poz1[i]+1;
     else
       count+=poz1[i]-poz2[i]+1;
fout=fopen(outfile,"w");
fprintf(fout,"%Ld\n",count);
fclose(fout);
return 0;
}