Cod sursa(job #1205916)

Utilizator IonSebastianIon Sebastian IonSebastian Data 8 iulie 2014 14:04:11
Problema Secventa 5 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.04 kb
#include <cstdio>

FILE* in;
FILE* out;

const int N = (1<<22), KEY = 1000001;

class H{
public:
    unsigned int lst[KEY], val[N+1], urm[N+1];
    unsigned int nr;
    bool contains(unsigned int element)
    {
        unsigned int place = lst[element%KEY];
        while(place != 0 && val[place] != element)
        {
            place = urm[place];
        }
        return (place != 0);
    }
    void push(unsigned int element)
    {
        unsigned int place = element%KEY;
        this->val[++this->nr] = element;
        this->urm[nr] = this->lst[place];
        this->lst[place] = this->nr;
    }
    void pop(unsigned int element)
    {
        unsigned int place = element%KEY;
        if(element == val[lst[place]])
        {
            lst[place] = urm[lst[place]];
            return;
        }
        place = lst[place];
        while(urm[place] != 0 && val[urm[place]] != element)
        {
            place = urm[place];
        }
        if(val[urm[place]] == element)
        {
            urm[place] = urm[urm[place]];
        }
    }
};

unsigned int v[N+1];

H hashLeft, hashRight;
int left = 0, right = 0, dLeft = 0, dRight = 0;
int n, l, u;
long long result;

int main()
{
    in = fopen("secv5.in","r");
    out = fopen("secv5.out","w");

    fscanf(in, "%d%d%d", &n,&l,&u);

    unsigned int i;

    for(i = 1; i <= n; i++)
    {
        fscanf(in, "%u", &v[i]);
    }

    bool na = false;

    while(dLeft < l && left < n)
    {
        left++;
        if(!hashLeft.contains(v[left]))
        {
            dLeft++;
        }
        hashLeft.push(v[left]);
    }
    while(dRight <= u && right <= n)
    {
        right++;
        if(!hashRight.contains(v[right]))
        {
            dRight++;
        }
        hashRight.push(v[right]);
    }
    hashRight.pop(v[right]);
    right--;
    dRight--;
    result = right - left + 1;
    for(i = 2; i <= n; i++)
    {
        hashLeft.pop(v[i-1]);
        hashRight.pop(v[i-1]);
        if(!hashLeft.contains(v[i-1]))
        {
            dLeft--;
            while(dLeft < l)
            {
                left++;
                if(left > n)
                {
                    na = true;
                    break;
                }
                if(!hashLeft.contains(v[left]))
                {
                    dLeft++;
                }
                hashLeft.push(v[left]);
            }
            if(na)
            {
                break;
            }
        }
        if(!hashRight.contains(v[i-1]))
        {
            dRight--;
            while(dRight <= u && right <= n)
            {
                right++;
                if(!hashRight.contains(v[right]))
                {
                    dRight++;
                }
                hashRight.push(v[right]);
            }
            hashRight.pop(v[right]);
            right--;
            dRight--;
        }
        result += right - left + 1;
    }
    fprintf(out,"%lld",result);
    return 0;
}