Cod sursa(job #1843122)

Utilizator oaspruOctavian Aspru oaspru Data 8 ianuarie 2017 10:20:38
Problema Secventa 5 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.85 kb
#include <stdio.h>
#include <stdlib.h>
 
#define MAX_N 1<<20
#define MAX_H 1<<18
#define HASH_SHIFT 14
#define FIN "secv5.in"
#define FOUT "secv5.out"
 
struct hash_line 
{
    unsigned val[4];
    int idx[4];
} H[2][MAX_H];
 
int N, L, R, A[MAX_N], cnt1[MAX_N], cnt2[MAX_N];
unsigned hash[2]; char buf[16];
long long Res;
 
inline int hash_insert(unsigned val, int idx)
{
    int i1, i2;
    hash_line *p1, *p2;
 
    p1 = H[0] + ((val * hash[0]) >> HASH_SHIFT);
    for (i1 = 0; i1 < 4 && p1->val[i1]; i1++)
        if (p1->val[i1] == val) return p1->idx[i1];
     
    p2 = H[1] + ((val * hash[1]) >> HASH_SHIFT);
    for (i2 = 0; i2 < 4 && p2->val[i2]; i2++)
        if (p2->val[i2] == val) return p2->idx[i2];
 
    if (i1 == 4 && i2 == 4)
    {
        fprintf(stderr, "REHASH!\n");
        return -1;
    }
 
    if (i1 > i2) 
        p2->val[i2] = val, p2->idx[i2] = idx;
    else
        p1->val[i1] = val, p1->idx[i1] = idx;
    return idx;
}
 
inline int read_int(void)
{
    int n = 0;
    char *p;
 
    fgets(buf, sizeof(buf), stdin);
    for (p = buf; *p >= '0' && *p <= '9'; p++)
        n = n*10 + *p-'0';
    return n;
}
 
int main(void)
{
    int i, l1, l2, n1, n2;
 
    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);
 
    scanf("%d %d %d\n", &N, &L, &R);
    srand(N);
    hash[0] = (rand()<<1)|1;
    hash[1] = (rand()<<1)|1;
    for (i = 0; i < N; i++)
        A[i] = hash_insert(read_int(), i);
 
    for (i = l1 = l2 = n1 = n2 = 0; i < N; i++)
    {
        if (++cnt1[A[i]] == 1) n1++;
        for (; n1 > R && l1 <= i; l1++)
            if (--cnt1[A[l1]] == 0) n1--;
 
        if (++cnt2[A[i]] == 1) n2++;
        for (; n2 >= L && l2 <= i; l2++)
            if (--cnt2[A[l2]] == 0) n2--;
 
        Res += l2-l1;
    }
 
    printf("%lld\n", Res);
 
    return 0;
}