Cod sursa(job #1464732)

Utilizator t.g.g.tt.g.g.t t.g.g.t Data 24 iulie 2015 13:35:23
Problema Atac Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.65 kb
#include <stdio.h>

struct cel
{
    int val;
    int cost;
    cel* urm;
};
typedef cel* lda;

lda lista[32005];

int pe[100005],nrniv,apare[32005][2];
int niv[32005];
int trecut[32005];

int rmq[100005][20];
int put[20];
int alaturi[100005];

int minim[32005][20][2];

void parc(int nod,int nv,int prec)
{
    trecut[nod]=1;
    niv[nod]=nv;
    ++nrniv;
    apare[nod][0]=nrniv;
    pe[nrniv] = niv[nod];

    int advr=0;
    for (lda p=lista[nod]; p!=0; p=p->urm)
    {
        if(p->val==prec)
        {
            minim[nod][0][0]=p->cost;
        }
        if (trecut[p->val]==0)
        {
            parc(p->val,nv+1,nod);
            ++nrniv; pe[nrniv]=niv[nod]; advr=1;
        }
    }

    if (prec==0) minim[nod][0][0]=1000000;
    minim[nod][0][1]=prec;
    for (int i=1; i<20; ++i)
    {
        if (minim[nod][i][1]>0)
        {
            minim[nod][i][0]=minim[minim[nod][i-1][1]][i-1][0];
            if (minim[nod][i-1][0]<minim[nod][i][0]) minim[nod][i][0]=minim[nod][i-1][0];
            minim[nod][i][1]=minim[minim[nod][i-1][1]][i-1][1];
        }else
        {
            minim[nod][i][0]=minim[nod][i-1][0];
            minim[nod][i][1]=minim[nod][i-1][1];
        }
    }

    if (advr==0)
    {
        ++nrniv;
        pe[nrniv] = niv[nod];
    }
    apare[nod][1]=nrniv;
}

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

    int n,m,p;
    scanf("%d %d %d",&n,&m,&p);

    for (int i=2; i<=n; ++i)
    {
        int u,v;
        scanf("%d %d",&u,&v);

        lda p=new cel;
        p->val = u;
        p->cost = v;
        p->urm = lista[i];
        lista[i]=p;

        p=new cel;
        p->val = i;
        p->cost = v;
        p->urm = lista[u];
        lista[u] = p;
    }

    put[0]=1;
    for (int i=1; i<20;++i) { put[i]=put[i-1]*2; }
    int pos=0;
    for (int i=1; i<=100000; ++i)
    {
        if (i==put[pos+1]) pos++;
        alaturi[i]=pos;
    }

    parc(1,1,0);
    for (int i=nrniv; i>0; --i)
    {
        rmq[i][0]=pe[i];
        for (int j=1; j<20; ++j)
        {
            if (i+put[j-1]<=nrniv)
            {
                rmq[i][j]=rmq[i+put[j-1]][j-1];
                if (rmq[i][j-1]<rmq[i][j]) rmq[i][j] = rmq[i][j-1];
            }else
            {
                rmq[i][j]=rmq[i][j-1];
            }
        }
    }

    int x,y,a,b,c,d;
    int z;
    scanf("%d %d %d %d %d %d",&x,&y,&a,&b,&c,&d);

    for (int i=1; i<=m; ++i)
    {
        int st,dr;
        if (apare[x][0]<apare[y][0])
        {
            st=apare[x][0];
            dr=apare[y][1];
        }else
        {
            st=apare[y][0];
            dr=apare[x][1];
        }

        int val = alaturi[dr-st+1];
        int care = rmq[st][val];
        if (rmq[dr-put[val]+1][val]<care) care=rmq[dr-put[val]+1][val];

        int z=1000000;

        int cauta=niv[x]-care+1;
        int nod=x;
        while (cauta>0)
        {
            if (nod>0) if (minim[nod][alaturi[cauta]][0]<z) z=minim[nod][alaturi[cauta]][0];
            nod = minim[nod][alaturi[cauta]][1];
            cauta-=put[alaturi[cauta]];
        }

        cauta=niv[y]-care+1;
        nod=y;
        while (cauta>0)
        {
            if (nod>0) if (minim[nod][alaturi[cauta]][0]<z) z=minim[nod][alaturi[cauta]][0];
            nod = minim[nod][alaturi[cauta]][1];
            cauta-=put[alaturi[cauta]];
        }

        if (i>m-p)
        {
            printf("%d\n",z);
        }

        x = 1 + (a*x + b*y)%n;
        y = 1 + (c*y + d*z)%n;
    }

    fclose(stdin);
    fclose(stdout);
    return 0;
}