Cod sursa(job #378105)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 27 decembrie 2009 15:50:02
Problema Secventa 5 Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.7 kb
#include <cstdio>

using namespace std;

const int MAXN = 1 << 20;
const int SHIFT = 14;
const int MAXH = 1 << (32-SHIFT);
const int MAXC = 3;
const int MAXB = 13;
const unsigned int R = 892837121;
    
int N, X, Y;
long long Sol;
unsigned int A[MAXN];
unsigned int H[2][MAXH][MAXC];
int C[2][MAXH][MAXC];

inline int addToHash(int w, unsigned int x)
{
    int v = (x * R) >> SHIFT, i;

    for (i = 0; C[w][v][i] != 0; ++i)
        if (H[w][v][i] == x) 
        {
            ++C[w][v][i];
            return 0;
        }

    H[w][v][i] = x;
    C[w][v][i] = 1;
    return 1;
}

inline int removeFromHash(int w, unsigned int x)
{
    int v = (x * R) >> SHIFT;

    for (int i = 0; C[w][v][i] != 0; ++i)
        if (H[w][v][i] == x)
        {
            --C[w][v][i];

            if (C[w][v][i]) return 0;
        
            int j = i;
            while (C[w][v][j+1] != 0) ++j;

            H[w][v][i] = H[w][v][j];
            C[w][v][i] = C[w][v][j];
            C[w][v][j] = 0;

            return 1;
        }

    return 0;
}

long long solve(int w, int X)
{
    int cnt = 0;
    long long res = 0;

    for (int i = 1, j = 1; i <= N; ++i)
    {
        cnt += addToHash(w, A[i]);
        
        for (; j <= i && cnt > X; ++j) cnt -= removeFromHash(w, A[j]);

        res += i-j+1;
    }

    return res;
}

int main()
{
    freopen("secv5.in", "r", stdin);
    freopen("secv5.out", "w", stdout);

    char buff[MAXB];

    scanf("%d %d %d ", &N, &X, &Y);

    for (int i = 1; i <= N; ++i) 
    {
        fgets(buff, MAXB, stdin);

        for (int j = 0; '0' <= buff[j] && buff[j] <= '9'; ++j) 
            A[i] = A[i]*10 + buff[j]-'0';
    }

    Sol = solve(0, Y) - solve(1, X-1);

    printf("%lld\n", Sol);

    return 0;
}