Cod sursa(job #943668)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 26 aprilie 2013 08:46:00
Problema Secventa 5 Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.83 kb
#include <fstream>
#include <iostream>
#include <map>
#include <hash_map>
#include <iterator>
#include <algorithm>
#include <vector>
#include <cstring>
 
#define MAXN ((1<<20) + 1)
#define HASH_SIZE 1572869
 
using namespace std;
//using namespace __gnu_cxx;
 
unsigned int vec[MAXN];
int minimumSpans[MAXN];

unsigned fnv_hash (unsigned int key)
{
    unsigned char *p = reinterpret_cast<unsigned char*>(&key);
    unsigned int h = 2166136261;

    for (int i = 0; i < sizeof(unsigned int); i++ )
    {
        h = ( h * 16777619 ) ^ p[i];
    }

    return h;
}

typedef unsigned int uint32;

class HashTable
{
public:
    uint32& operator [] (uint32 key)
    {
        uint32 hash = key;
         
        hash = hash % HASH_SIZE;
         
        vector<pair<uint32,uint32> >::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 = hash % HASH_SIZE;
         
        vector<pair<uint32,uint32> >::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, vector<pair<uint32,uint32> >::iterator& it)
    {
        uint32 hash = key;
        hash = hash % HASH_SIZE;
         
        table[hash].erase(it);
    }
     
private:
    struct FindKey
    {
        FindKey(uint32 key) :
            keyToFind(key)
        {}
 
        bool operator () (const pair<uint32,uint32>& kvp) const
        {
            return kvp.first == keyToFind;
        }
         
        uint32 keyToFind;
    };
 
    vector<pair<uint32,uint32> > table[HASH_SIZE];
};

HashTable mapDistincts;
HashTable mapDistincts2;
 
int main()
{
    int n, L, U;
    long long numSecv = 0;
    fstream fin("secv5.in", fstream::in);
    fstream fout("secv5.out", fstream::out);
     
    fin >> n >> L >> U;
    //cout << n << " " << L << " " << U << endl;
     
    for (int i=1; i<=n; ++i)
    {
        fin >> vec[i];
        //cout << vec[i] << " ";
    }
    //cout << endl;
 
    //hash_map<int, int> mapDistincts;
    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;
    }
     
    //ostream_iterator<int> itOut(cout, " ");
    //copy(minimumSpans, minimumSpans + n + 1, itOut);
    //cout << endl;

    distincts = 0;
    span = 1;
     
    for (int i=1; i<=n; ++i)
    {
        mapDistincts2[vec[i]]++;
        if (mapDistincts2[vec[i]] == 1)
        {
            distincts++;
        }
         
        while (distincts > U)
        {
            mapDistincts2[vec[span]]--;
            if (mapDistincts2[vec[span]] == 0)
            {
                distincts--;
            }
             
            span++;
        }
         
        //maximumSpans[i] = span;
         
        numSecv += (minimumSpans[i] - span);
    }
 
    //copy(maximumSpans, maximumSpans + n + 1, itOut);
    //cout << endl;
     
    fout << numSecv << "\n";
     
    return 0;
}