Cod sursa(job #943996)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 27 aprilie 2013 00:03:19
Problema Secventa 5 Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 4 kb
#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <cstring>
     
#define MAXN ((1<<20) + 1)
#define HASH_SIZE 38993
     
using namespace std;
     
unsigned int vec[MAXN];
    
typedef unsigned int uint32;
typedef vector<pair<uint32,uint32> > HashBucket;
    
class HashTable
{
public:
    uint32& operator [] (uint32 key)
    {
        uint32 hash = key % HASH_SIZE;
             
        HashBucket::iterator it = find_if(table[hash].begin(), table[hash].end(), FindKey(key));
        if (it != table[hash].end())
        {
            return it->second;
        }
             
        table[hash].push_back(make_pair(key, 0));
             
        return table[hash][table[hash].size() - 1].second;
    }
         
    bool find(uint32 key, uint32& val) const
    {
        uint32 hash = key % HASH_SIZE;
             
        HashBucket::const_iterator it = find_if(table[hash].begin(), table[hash].end(), FindKey(key));
        if (it != table[hash].end())
        {
            val = it->second;
            return true;
        }
             
        return false;
    }
         
    void erase(uint32 key, HashBucket::iterator& it)
    {
        uint32 hash = key % HASH_SIZE;
             
        table[hash].erase(it);
    }
       
    void clear()
    {
        for (int i=0; i<HASH_SIZE; ++i)
        {
            table[i].clear();
        }
    }
         
private:
    struct FindKey
    {
        FindKey(uint32 key) :
            keyToFind(key)
        {}
     
        bool operator () (const pair<uint32,uint32>& kvp) const
        {
            return kvp.first == keyToFind;
        }
             
        uint32 keyToFind;
    };
     
    HashBucket table[HASH_SIZE];
};
    
HashTable mapDistinctsL;
HashTable mapDistinctsU;
   
int main()
{
    int n, L, U;
    long long numSecv = 0;
    fstream fin ("secv5.in" , fstream::in);
    fstream fout("secv5.out", fstream::out);
      
    fin.seekg(0, ios::end);
    int end = fin.tellg();
      
    char* buffer = static_cast<char*>(malloc(end));
  
    fin.seekg (0, ios::beg);
    fin >> n >> L >> U;
    //cout << n << " " << L << " " << U << endl;
      
    fin.read(buffer, end);
  
    char* pCurrent = buffer;
    for (int i=1; i<=n; ++i)
    {
        pCurrent++;
        while (*pCurrent >= '0' && *pCurrent <= '9')
        {
            vec[i] = 10*vec[i] + (*pCurrent - 48);
            pCurrent++;
        }
    }
    /*for (int i=1; i<=n; ++i)
    {
        fin >> vec[i];
    }*/
    //cout << endl;
      
    //free(buffer);

    unsigned int distinctsL = 0;
    int spanL = 1;
    
    unsigned int distinctsU = 0;
    int spanU = 1;
         
    for (int i=1; i<=n; ++i)
    {
        mapDistinctsL[vec[i]]++;
        if (mapDistinctsL[vec[i]] == 1)
        {
            distinctsL++;
        }
             
        while (distinctsL > L-1)
        {
            //cout << "Count " << vec[spanL] << " " << mapDistinctsL[vec[spanL]] << endl;
            mapDistinctsL[vec[spanL]]--;
            if (mapDistinctsL[vec[spanL]] == 0)
            {
                distinctsL--;
            }
            
            mapDistinctsU[vec[spanL]]++;
            if (mapDistinctsU[vec[spanL]] == 1)
            {
                distinctsU++;
            }
            
            spanL++;
            
            //cout << distinctsU << " " << U - L + 1 << endl;
            
            while (distinctsU > U - L + 1)
            {
                mapDistinctsU[vec[spanU]]--;
                if (mapDistinctsU[vec[spanU]] == 0)
                {
                    distinctsU--;
                }
                     
                spanU++;
            }
        }
        
        //cout << spanL << " - " << spanU << " = " << spanL - spanU << endl;

        numSecv += (spanL - spanU);
    }
         
    fout << numSecv << "\n";
         
    return 0;
}