Cod sursa(job #651235)

Utilizator unholyfrozenCostea Andrei unholyfrozen Data 20 decembrie 2011 00:23:25
Problema Secventa 5 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.48 kb
#include <cstdio>
#include <map>
#include <cstring>

using namespace std;

const int NMAX = 1 << 20;
const int modulo = 666013;


struct nod
{
    int poz;
    nod* next;
    nod* prev;
};

struct hashnod
{
    unsigned int val;
    nod* x;
    hashnod* next;
};

hashnod* M[modulo];

int N, L, U;
unsigned int V[NMAX];

nod* find(unsigned int val)
{
    int wh = val % modulo;
    
    while(M[wh] != NULL)
        if(M[wh]->val == val)
            return M[wh]->x;
    return NULL;
}

void insert(int val, nod* x)
{
    int wh = val % modulo;
    hashnod* new_hashnod = new hashnod;
    new_hashnod->next = M[wh];
    new_hashnod->val = val;
    new_hashnod->x = x;
    M[wh] = new_hashnod;
}

int main()
{
    freopen("secv5.in", "r", stdin);
    freopen("secv5.out", "w", stdout);
    
    scanf("%d %d %d ", &N, &L, &U);
    
    char buf[32];
    
    for(int i = 0; i < N; i++)
    {
        fgets(buf, sizeof(buf), stdin);
        int n = strlen(buf);
        buf[n-1] = 0;
        n--;
        for(int j = 0; j < n; j++)
            V[i] = V[i]*10 + buf[j] - '0';
    }    
    
    long long result = 0;
    
    nod* head = new nod;
    head->next = NULL;
    head->prev = NULL;
    head->poz = N - 1;
    insert(V[N - 1], head);
    nod* l = head, *u = head;
    
    U++;
    if(L == 1) result++;
    
    int nr_elem = 1;
    
    for(int i = N - 2; i >= 0; i--)
    {
        nod* prev = find(V[i]);
        
        if(prev == NULL)
        {
            nod* new_nod = new nod;
            new_nod->poz = i;
            new_nod->prev = NULL;
            new_nod->next = head;
            head->prev = new_nod;
            head = new_nod;
            insert(V[i], new_nod);
            
            nr_elem++;
            
            if(nr_elem > L) l = l->prev;
            if(nr_elem > U) u = u->prev;
        }
        else
        {
            if(prev == head);
            else
            if(prev->poz < l->poz)
            {
                nod* prevnod = prev->prev;
                nod* nextnod = prev->next;
                     
                prevnod->next = nextnod;
                nextnod->prev = prevnod;
                prev->prev = NULL;
                prev->next = head;
                head->prev = prev;
                head = prev;
            }
            else if(prev->poz < u->poz)
            {   
                nod* prevnod = prev->prev;
                nod* nextnod = prev->next;
                     
                prevnod->next = nextnod;
                nextnod->prev = prevnod;
                prev->prev = NULL;
                prev->next = head;
                head->prev = prev;
                head = prev;
                
                if(l == prev)
                    l = prevnod;
                else l = l->prev;
            }
            else
            {   
                nod* prevnod = prev->prev;
                nod* nextnod = prev->next;
                     
                prevnod->next = nextnod;
                if(nextnod != NULL)
                nextnod->prev = prevnod;
                prev->prev = NULL;
                prev->next = head;
                head->prev = prev;
                head = prev;
                
                if(prev == u)
                    u = prevnod;
                else if(nr_elem > U) u = u->prev;
                
                if(nr_elem > L) l = l->prev;
            }
            prev->poz = i;
        }
        result += (nr_elem < U ? N : u->poz) - (nr_elem < L ? N : l->poz);
    }
    
    printf("%lld\n", result);
    return 0;
}