Cod sursa(job #944298)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 28 aprilie 2013 02:56:25
Problema Secventa 5 Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.3 kb
#include <fstream>
#include <iostream>
#include <map>
#include <hash_map>
#include <iterator>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cstdlib>
      
#define MAXN ((1<<20) + 1)
#define HASH_SIZE 38993
      
using namespace std;
      
unsigned int vec[MAXN];
int minimumSpans[MAXN];
     
typedef unsigned int uint32;
 
struct Bucket
{
    uint32 Key;
    uint32 Count;
};

struct HashBucket
{
    HashBucket() :
        Size(0),
        Capacity(2),
        Entries((Bucket*)malloc(2 * sizeof(Bucket)))
    {}
    
    Bucket& operator [] (int index)
    {
        return Entries[index];
    }
    
    int size() const
    {
        return Size;
    }
    
    void push_back(Bucket b)
    {
        if (Size == Capacity)
        {
            Capacity += 5;
            Bucket* ptr = (Bucket*)realloc(Entries, Capacity * sizeof(Bucket));
            Entries = ptr;
        }
        
        Entries[Size] = b;
        Size++;
    }
    
    void clear()
    {
        Size = 0;
    }
    
    int Size;
    int Capacity;
    Bucket* Entries;
};
 
//typedef vector<Bucket> HashBucket;
 
class HashTable
{
public:
    uint32& operator [] (uint32 key)
    {
        uint32 hash = key % HASH_SIZE;
        
        int i = 0;
        int j = table[hash].size();
        
        for (int i=0; i<table[hash].size(); ++i)
        {
            if (table[hash][i].Key == key)
            {
                return table[hash][i].Count;
            }
        }
         
        Bucket b = {key, 0};
        table[hash].push_back(b);
              
        return table[hash][table[hash].size() - 1].Count;
    }
        
    void clear()
    {
        /*int vec[50] = {0};
        int countZero = 0;
        int countOne = 0;
        int countMore = 0;
        int maxFill = 0;
        fstream fout("hash_log.txt", fstream::out);
        for (int i=0; i<HASH_SIZE; ++i)
        {
            switch (table[i].size())
            {
                case 0:
                    countZero++;
                    break;
                case 1:
                    countOne++;
                    break;
                default:
                    countMore++;
            }
             
            maxFill = max(maxFill, (int)table[i].size());
             
            vec[(int)table[i].size()]++;
 
            fout << table[i].size() << " ";
            table[i].clear();
        }
        fout << "\n";
        fout.close();
         
        cout << countZero << " " << countOne << " " << countMore << " " << maxFill << "\n";
         
        for (int i=0; i<50; ++i)
        {
            cout << vec[i] << " ";
        }
        cout << endl;*/
         
        for (int i=0; i<HASH_SIZE; ++i)
        {
            table[i].clear();
        }
    }
          
private:
      
    HashBucket table[HASH_SIZE];
};
     
HashTable mapDistincts;
      
int main()
{
    int n, L, U;
    long long numSecv = 0;
    fstream fin("secv5.in" , fstream::in);
    fstream fout("secv5.out", fstream::out);
     
    /*std::default_random_engine gen;
    std::uniform_int_distribution<int> dis(0,1<<31);
     
    fout << MAXN << " " << MAXN / 2 << " " << MAXN - 1 << "\n";
    for (int i=1; i<=MAXN; ++i)
    {
        fout << dis(gen) << "\n";
    }
     
    fout.close();
 
    return 0;*/
       
    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);
    //cout << buffer << endl;
   
    char* pCurrent = buffer;
    for (int i=1; i<=n; ++i)
    {
        //fin >> vec[i];
        pCurrent++;
        while (*pCurrent >= '0' && *pCurrent <= '9')
        {
            vec[i] = 10*vec[i] + (*pCurrent - 48);
            pCurrent++;
        }
         
        //cout << vec[i] << " ";
    }
    //cout << endl;
       
    //free(buffer);
    unsigned int distincts = 0;
    int span = 1;
          
    for (int i=1; i<=n; ++i)
    {
        mapDistincts[vec[i]]++;
        if (mapDistincts[vec[i]] == 1)
        {
            distincts++;
            
            while (distincts > L-1)
            {
                mapDistincts[vec[span]]--;
                if (mapDistincts[vec[span]] == 0)
                {
                    distincts--;
                }
                      
                span++;
            }
        }
  
        minimumSpans[i] = span;
    }
        
    mapDistincts.clear();
     
    distincts = 0;
    span = 1;
          
    for (int i=1; i<=n; ++i)
    {
        mapDistincts[vec[i]]++;
        if (mapDistincts[vec[i]] == 1)
        {
            distincts++;
            
            while (distincts > U)
            {
                mapDistincts[vec[span]]--;
                if (mapDistincts[vec[span]] == 0)
                {
                    distincts--;
                }
                      
                span++;
            }
        }

        numSecv += (minimumSpans[i] - span);
    }
     
    //mapDistincts.clear();
          
    fout << numSecv << "\n";
          
    return 0;
}