Cod sursa(job #13497)

Utilizator stef2nStefan Istrate stef2n Data 6 februarie 2007 21:10:02
Problema Secventa 5 Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <stdio.h>

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

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

void citire()
  {
   fin=fopen(infile,"r");
   fscanf(fin,"%d %d %d",&n,&L,&U);
   for(int i=0;i<n;i++)
      fscanf(fin,"%u",&x[i]);
   fclose(fin);
  }

inline int h(unsigned int x)
  {
   return x%MOD;
  }

inline void adauga(unsigned int x)
  {
   int poz=h(x);
   NOD *b=hash[poz];
   while(b)
       {
        if(b->val==x)
          {
           b->count++;
           return;
          }
        b=b->adr;
       }
   b=new NOD;
   b->val=x;
   b->count=1;
   b->adr=hash[poz];
   hash[poz]=b;
  }

inline void sterge(unsigned int x)
  {
   int poz=h(x);
   NOD *b=NULL,*c=hash[poz];
   while(c)
       {
        if(c->val==x)
          {
           c->count--;
           if(!c->count)
             if(!b)
               hash[poz]=c->adr;
             else
               {
                b->adr=c->adr;
                delete c;
               }
           return;
          }
        b=c;
        c=c->adr;
       }
  }

inline NOD *cauta(unsigned int x)
  {
   int poz=h(x);
   NOD *b=hash[poz];
   while(b)
       {
        if(b->val==x)
          return b;
        b=b->adr;
       }
   return NULL;
  }

void solve1(int *poz, int DIM)
  {
   int i,lung=0,ind=-1,stop=0;
   NOD *b;
   for(i=0;i<MOD;i++)
      hash[i]=NULL;
   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++)
      hash[i]=NULL;
   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;
}