Cod sursa(job #9658)

Utilizator stef2nStefan Istrate stef2n Data 27 ianuarie 2007 16:34:34
Problema Secventa 5 Scor 50
Compilator cpp Status done
Runda Unirea 2007, clasele 11-12 Marime 2.23 kb
#include <stdio.h>
#include <set>
using namespace std;

#define infile "secv5.in"
#define outfile "secv5.out"
#define NMAX 1100000

// ma intereseaza cea mai scurta secventa care se termina pe poz I si care are L elem dist
// ma intereseaza cea mai lunga secventa care se termina pe poz I si care are U elem dist

FILE *fin,*fout;
long long x[NMAX];
int n,L,U;
multiset <long long> MS;
set <long long> S;
int pozmin[NMAX];
int pozmax[NMAX];

void solve_first()
  {
   int i,poz,sz;
   poz=0;
   for(i=0;i<n;i++)
      {
       S.insert(x[i]);
       MS.insert(x[i]);

       sz=S.size();

       if(sz<L)
         pozmin[i]=-1; // nu sunt destule elem distincte
       else
         {
          while(MS.count(x[poz])>1)
               {
                MS.erase(MS.find(x[poz]));
                poz++;
               }
          if(sz==L)
            pozmin[i]=poz;
          else // sz>L
            {
             MS.erase(x[poz]);
             S.erase(x[poz]);
             poz++;
             while(MS.count(x[poz])>1)
                  {
                   MS.erase(MS.find(x[poz]));
                   poz++;
                  }
             pozmin[i]=poz;
            }
         }
      }
  }


void solve_second()
  {
   int i,poz,sz;
   poz=0;
   for(i=0;i<n;i++)
      {
       S.insert(x[i]);
       MS.insert(x[i]);

       sz=S.size();

       if(sz<U)
         pozmax[i]=-1; // nu sunt destule elem distincte
       else
         {
          if(sz==U)
            pozmax[i]=poz;
          else // sz>U
            {
             while(sz>U)
                 {
                  MS.erase(MS.find(x[poz]));
                  if(MS.find(x[poz]) == MS.end())
                    {S.erase(x[poz]);
                     sz--;}
                  poz++;
                 }

             pozmax[i]=poz;
            }
         }
      }
  }



int main()
{
int i;
fin=fopen(infile,"r");
fscanf(fin,"%d %d %d",&n,&L,&U);
for(i=0;i<n;i++)
   fscanf(fin,"%Ld",&x[i]);
fclose(fin);
solve_first();
S.clear();
MS.clear();
solve_second();

long long solution=0;
for(i=0;i<n;i++)
   if(pozmin[i]!=-1)
     if(pozmax[i]==-1)
       solution+=pozmin[i]+1;
     else
       solution+=pozmin[i]-pozmax[i]+1;

fout=fopen(outfile,"w");
fprintf(fout,"%Ld\n",solution);
fclose(fout);
return 0;
}