Cod sursa(job #9773)

Utilizator georgianaGane Andreea georgiana Data 27 ianuarie 2007 16:55:57
Problema Secventa 5 Scor 0
Compilator cpp Status done
Runda Unirea 2007, clasele 11-12 Marime 3.95 kb
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

struct arb
{
	int x,ap,nrnoduri,h;
	struct arb *st,*dr,*tata;
};

long int n,num,l,u,st1,st2,nrst1,nrst2,a[1050000],v[1050000],app[1050000];
long long int nr_secv;
struct arb *a1, *a2;

void put(struct arb *p)
{
    if (p!=NULL)
    {
        put(p->st);
        v[++num]=p->x;
        app[num]=p->ap;
        put(p->dr);
        free(p);               
    }
}

void go(struct arb *p,int i,int j)
{
     int m=(i+j)/2;
     p->x=v[m];
     p->ap=app[m];
     p->nrnoduri=j-i+1;
     p->h=(int)ceil(log(j-i+1));
     if (m>i)
     {
         p->st=(struct arb*)malloc(sizeof(struct arb));
         p->st->tata=p;
         go(p->st,i,m-1);    
     }
     else p->st=NULL;
     
     if (m<j)
     {
         p->dr=(struct arb*)malloc(sizeof(struct arb));
         p->dr->tata=p;
         go(p->dr,m+1,j);
     }
     else p->dr=NULL;
}

void reconstr(struct arb *p)
{
     num=0;
     put(p->st);
     v[++num]=p->x;
     app[num]=p->ap;
     put(p->dr);
     go(p,1,num);
}

void add(struct arb *p, long int val)
{
    struct arb *q,*t;
    q=p; t=NULL;
    while (q!=NULL && q->x!=val)
       if (val<q->x) t=q,q=q->st;
       else t=q,q=q->dr;
    if (q!=NULL) { q->ap=1; return; }
    q=(struct arb*) malloc(sizeof(struct arb));
    q->x=val;
    q->ap=1;
    q->dr=NULL;
    q->st=NULL;
    q->tata=t;
    if (val<t->x) t->st=q;
    else t->dr=q;
    q->nrnoduri=1; q->h=1;

    while (t!=NULL)
    {
        (t->nrnoduri)++;
        t->h=0;
        if (t->st!=NULL && t->st->h>t->h) t->h=t->st->h;
        if (t->dr!=NULL && t->dr->h>t->h) t->h=t->dr->h;
        (t->h)++;
        if ((t->h)>2*log(1+t->nrnoduri)) reconstr(t);
        t=t->tata;
    }

}

int find(struct arb *p, long int val)
{
    struct arb *q;
    q=p;
    while (q!=NULL && q->x!=val)
       if (val<q->x) q=q->st;
       else q=q->dr;
    if (q==NULL || q->ap==0) return 0;
    (q->ap)++;
    return 1;
}

int elim(struct arb *p, long int val)
{
    struct arb *q;
    q=p;
    while (q->x!=val)
       if (val<q->x) q=q->st;
       else q=q->dr;
    (q->ap)--;
    if (q->ap==0) return 1;
    return 0;
}

int elim2(struct arb *p, long int val)
{
    struct arb *q;
    q=p;
    while (q->x!=val)
       if (val<q->x) q=q->st;
       else q=q->dr;
    if (q->ap==1) return 1;
    (q->ap)--;
    return 0;
}

void elib(struct arb *p)
{
     if (p->st!=NULL) {
                         elib(p->st);
                         free(p->st);
                      }
     if (p->dr!=NULL) {
                         elib(p->dr);
                         free(p->dr);
                      }
}

int main()
{
    freopen("secv5.in","r",stdin);
    scanf("%d %d %d",&n,&l,&u);
    scanf("%d",&a[0]);
    st1=0; st2=0;
    nrst1=1; nrst2=1;
    a1=(struct arb*) malloc(sizeof(struct arb));
    a1->x=a[0]; a1->ap=1;
    a1->dr=NULL; a1->st=NULL;
    a1->tata=NULL;
    a1->nrnoduri=1;
    a1->h=1;
    a2=(struct arb*) malloc(sizeof(struct arb));
    a2->x=a[0]; a2->ap=1;
    a2->dr=NULL; a2->st=NULL;
    a2->tata=NULL;
    a2->nrnoduri=1;
    a2->h=1;
    nr_secv=0;
    for (int i=1;i<n;i++)
    {
        scanf("%d",&a[i]);
        if (!find(a1,a[i]))
        {
            add(a1,a[i]);
            if (nrst1<u) nrst1++;
            else {
                     while (!elim(a1,a[st1])) st1++;
                     st1++;
                 }
        }
        if (!find(a2,a[i]))
        {
            add(a2,a[i]);
            if (nrst2<l) nrst2++;
            else {
                     while (!elim(a2,a[st2])) st2++;
                     st2++;
                 }
        }
        while (!elim2(a2,a[st2])) st2++;
        if (nrst2==l) nr_secv+=st2-st1+1;
    }
    elib(a1); free(a1);
    elib(a2); free(a2);
    freopen("secv5.out","w",stdout);
    printf("%I64d\n",nr_secv);
    fclose(stdout);
    return 0;
}