Cod sursa(job #211012)

Utilizator stef2nStefan Istrate stef2n Data 30 septembrie 2008 11:42:43
Problema Secventa 5 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.02 kb
#include <stdio.h>
#include <string.h>

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

FILE *fin,*fout;
int n,L,U;
unsigned int x[NMAX];
int norm[NMAX],used[NMAX];
NOD *hash[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, unsigned int dir)
  {
   NOD *a=new NOD;
   a->x=x;
   a->dir=dir;
   a->adr=hash[x%MOD];
   hash[x%MOD]=a;
  }

inline int cauta(unsigned int x)
  {
   NOD *b=hash[x%MOD];
   while(b)
       {
        if(b->x==x)
          return b->dir;
        b=b->adr;
       }
   return 0;
  }

void normalizare()
  {
   int i,count=0;
   for(i=0;i<MOD;i++)
      hash[i]=NULL;
   for(i=0;i<n;i++)
      {
       norm[i]=cauta(x[i]);
       if(!norm[i])
         {
          adauga(x[i],++count);
          norm[i]=count;
         }
      }
  }

void solve_min_L()
  {
   int i,ind=-1,lung=0,stop;
   memset(used,0,(n+1)*sizeof(int));
   for(i=0;i<n;i++)
      {
       if(!used[norm[i]])
         lung++;
       used[norm[i]]++;
       if(lung==L)
         {
          if(ind==-1)
            ind=0;
          while(used[norm[ind]]>1)
               {used[norm[ind]]--;
                ind++;}
         }
       else
         if(lung>L)
           {
            stop=0;
            while(used[norm[ind]]>0 && !stop)
                 {if(used[norm[ind]]==1)
                    stop=1;
                  used[norm[ind]]--;
                  ind++;}
            lung--;
            while(used[norm[ind]]>1)
                 {used[norm[ind]]--;
                  ind++;}
           }
       poz1[i]=ind;
      }
  }

void solve_max_U()
  {
   int i,ind=-1,lung=0,stop;
   memset(used,0,(n+1)*sizeof(int));
   for(i=0;i<n;i++)
      {
       if(!used[norm[i]])
         lung++;
       used[norm[i]]++;
       if(lung==U)
         {
          if(ind==-1)
            ind=0;
         }
       else
         if(lung>U)
           {
            stop=0;
            while(used[norm[ind]]>0 && !stop)
                 {if(used[norm[ind]]==1)
                    stop=1;
                  used[norm[ind]]--;
                  ind++;}
            lung--;
           }
       poz2[i]=ind;
      }
  }


int main()
{
long long COUNT=0;
citire();
normalizare();
solve_min_L(); // cea mai scurta secventa cu L numere distincte
solve_max_U(); // cea mai lunga secventa cu U numere distincte
for(int 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;
}