Cod sursa(job #345104)

Utilizator RobybrasovRobert Hangu Robybrasov Data 1 septembrie 2009 18:28:32
Problema Secventa 5 Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <cstdio>
#include <cstring>
#include <vector>
#define N 1050000
#define MOD 666013
#define S_MAX 65536

using namespace std;

struct hash
{
    unsigned int val,count;
};

unsigned int A[N],V[N],B[N]; //A - normalizarea, V - de cate ori e numarul, B - vectorul cu solutiile
vector<hash> L[MOD];
char S[S_MAX];
int poz=-1;

void insert(hash x)
{
    int nr=x.val%MOD;
    L[nr].push_back(x);
}

int exists(unsigned int x)
{
    int nr=x%MOD;
    vector<hash>::iterator it;
    for (it=L[nr].begin(); it!=L[nr].end() && it->val!=x; it++);

    if (it==L[nr].end()) return 0;
    else return it->count;
}

void read(unsigned int &x)
{
    x=0;
    for (; S[poz]<'0' || S[poz]>'9'; ++poz)
        if (poz==S_MAX-1)
        {
            fread(S,1,S_MAX,stdin);
            poz=-1;
        }

    for (; S[poz]>='0' && S[poz]<='9'; ++poz)
    {
        x=10*x+S[poz]-'0';
        if (poz==S_MAX-1)
        {
            fread(S,1,S_MAX,stdin);
            poz=-1;
        }
    }
}

int main()
{
    unsigned int n,l,u,i,x,nr,ind,kont=0;
    unsigned long long s1=0,s2=0;
    hash h;
	freopen("secv5.in","r",stdin);
	freopen("secv5.out","w",stdout);
	fread(S,1,S_MAX,stdin);
    read(n); read(l); read(u);
    //citire si crearea normalizarii in vectorul A
    for (i=1; i<=n; i++)
    {
        read(x);
        if (!exists(x))
        {
            kont++;
            h.val=x; h.count=kont;
            insert(h);
            A[i]=kont;
        }
        else A[i]=exists(x);
    }
    //parcurgerea si crearea vectorului B in care se va tine rezultatul pentru l-1
    l--;
    nr=0;
    ind=1;
    for (i=1; i<=n; i++)
    {
        if (!V[A[i]]) nr++;
        V[A[i]]++;

        for (; nr>l; ind++)
        {
            V[A[ind]]--;
            if (!V[A[ind]]) nr--;
        }

        B[i]=ind;
    }

    for (i=1; i<=n; i++) s1+=i-B[i]+1;
    //calcularea pentru u
    memset(V,0,sizeof(V));

    V[A[1]]=1;
    nr=1;
    ind=1;
    for (i=2; i<=n; i++)
    {
        if (!V[A[i]]) nr++;
        V[A[i]]++;

        for (; nr>u; ind++)
        {
            V[A[ind]]--;
            if (!V[A[ind]]) nr--;
        }

        B[i]=ind;
    }

    for (i=1; i<=n; i++) s2+=i-B[i]+1;

    printf("%lld",s2-s1);

    return 0;
}