Cod sursa(job #1248731)

Utilizator szabibibiOrban Szabolcs szabibibi Data 25 octombrie 2014 21:30:54
Problema Secventa 5 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <unordered_map>

using namespace std;

#define PRIME_MAX 104729

class HashMap
{
public:
    HashMap() :
        keyCount(0)
    {
    }

    void PutValue(unsigned int val)
    {
        std::vector<pair<unsigned int, unsigned int> > &list = hashTable[GetHashIndex(val)];
        std::vector<pair<unsigned int, unsigned int> >::iterator it = list.begin();
        for (; it != list.end() && it->first != val; it++);
        if (it == list.end())
        {
            list.push_back(make_pair(val, 1));
            keyCount++;
        }
        else
        {
            if (it->second == 0)
            {
                keyCount++;
            }
            it->second++;
        }
    }

    void RemoveValue(unsigned int val)
    {
        std::vector<pair<unsigned int, unsigned int> > &list = hashTable[GetHashIndex(val)];
        std::vector<pair<unsigned int, unsigned int> >::iterator it = list.begin();
        for (; it != list.end() && it->first != val; it++);
        if (it == list.end())
        {
            return;
        }
        else
        {
            it->second--;

            if (it->second == 0)
            {
                keyCount--;
            }
        }
    }

    unsigned int GetKeyCount()
    {
        return keyCount;
    }

private:
    vector<pair<unsigned int, unsigned int> > hashTable[PRIME_MAX];
    unsigned int keyCount;

    unsigned int GetHashIndex(unsigned int val)
    {
        return val % PRIME_MAX;
    }
};

unsigned int arr[1 << 20];
unsigned int n, l, u;
long long rez = 0;
HashMap h1, h2;


void GoUntilPossible(unsigned int &start, unsigned int &end, unsigned int &min_length)
{
    for (; min_length < n && h1.GetKeyCount() < l; min_length++)
    {
        h1.PutValue(arr[min_length]);
    }
    for (; end < n && h2.GetKeyCount() <= u; end++)
    {
        h2.PutValue(arr[end]);
    }
}

bool IsOK(unsigned int start, unsigned int end, unsigned int min_length)
{
    unsigned int ck1 = h1.GetKeyCount();
    unsigned int ck2 = h2.GetKeyCount();
    return (ck1 >= l && ck2 <= (u + 1)) && (ck2 >= l && ck2 <= (u + 1));
}

void AddSubsequences(unsigned int start, unsigned int end, unsigned int min_length)
{
    if (end == n && h2.GetKeyCount() <= u)
    {
        rez += (end + 1 - min_length);
    }
    else
    {
        rez += (end - min_length);
    }
}

void Advance(unsigned int &start, unsigned int &end, unsigned int &min_length)
{
    h1.RemoveValue(arr[start]);
    h2.RemoveValue(arr[start]);
    start++;
}

void Solve()
{
    unsigned int start = 0;
    unsigned int end = 0;
    unsigned int min_length = 0;

    do
    {
        GoUntilPossible(start, end, min_length);
        if (IsOK(start, end, min_length))
        {
            AddSubsequences(start, end, min_length);
        }
        Advance(start, end, min_length);
    } while (start < n);
}



void Read()
{
    ifstream f("secv5.in");

    f >> n >> l >> u;

    for (unsigned int i = 0; i < n; i++)
    {
        f >> arr[i];
    }
}

void Write()
{
    ofstream g("secv5.out");
    g << rez << endl;
    cout << rez << endl;
}

int main()
{
    Read();
    Solve();
    Write();

    return 0;
}