Cod sursa(job #1424076)

Utilizator heracleRadu Muntean heracle Data 23 aprilie 2015 13:26:32
Problema Heavy Path Decomposition Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 4.33 kb
#include <cstdio>
#include <cstdlib>

FILE* in=fopen("heavypath.in","r");
FILE* out=fopen("heavypath.out","w");

const int Q=100007;

int val[2*Q],nxt[2*Q],lst[Q],nr;

struct Nod;

int n,q;


int max(const int &a, const int &b)
{
    return a>b?a:b;
}

int ai[10*Q];

int lastloc=0;

struct arbore
{
 //   int *ai;
    int dim;
    int cst;

    arbore(int dimensiune)
    {
     //   ai=(int*) malloc(2*dimensiune+50);
      //  ai=new int[2*dimensiune+50];
        dim=dimensiune;
        cst=lastloc;
        lastloc+=2*dim+50;
    }

    void update(int p, int st, int dr, int poz, int val)
    {
        if(st==dr)
        {
            ai[cst+p]=val;
            return;
        }

        int md=(st+dr)/2;

        if(poz<=md)
            update(p*2,st,md,poz,val);
        else
            update(p*2+1,md+1,dr,poz,val);
        ai[cst+p]=max(ai[cst+p*2],ai[cst+p*2+1]);
    }

    int query(int p, int st, int dr, int a, int b)
    {
        if(b<st || a>dr)
            return 0;
        if(a<=st && b>=dr)
            return ai[cst+p];

        return max(query(p*2,st,(st+dr)/2,a,b), query(p*2+1,(st+dr)/2+1,dr,a,b));
    }
};

struct Lant
{
    int lengh;
    Nod *varf;

    arbore *arb;

    void finise()
    {
        if(arb==NULL)
            arb=new arbore(lengh);
    }

    void update(int poz, int val)
    {
        arb->update(1,1,lengh,poz,val);
    }

    int query(int st, int dr)
    {
        return arb->query(1,1,lengh,st,dr);
    }

} l[Q];

struct Nod
{
    int h;
    int c;
    int fii;
    Lant *lant;
    Nod *tata;
} v[Q];

int last_lant=1;

void main2()
{
    int t,x,y;

    for(int i=1; i<=q; i++)
    {
        fscanf(in,"%d%d%d",&t,&x,&y);

        if(t==0)
        {
        //    l[v[x].lant].update(v[x].h-v[l[v[x].lant].varf].h+1,y);
            v[x].lant->update(v[x].h-v[x].lant->varf->h+1,y);
        }
        else
        {
            int act=0;

            Nod *a,*b;

            a=&v[x];
            b=&v[y];

            while(a->lant!=b->lant)
            {
                if(a->lant->varf->tata->h  >  b->lant->varf->tata->h)
                {
                    act=max(act,a->lant->query(1,a->h - a->lant->varf->h +1 ));
                    a=a->lant->varf->tata;
                }
                else
                {
                    act=max(act,b->lant->query(1,b->h - b->lant->varf->h+1));
                    b=b->lant->varf->tata;
                }
            }
            if(a->h > b->h )
                act=max(act,a->lant->query(b->h- b->lant->varf->h+1,a->h - a->lant->varf->h+1));
            else
                act=max(act,a->lant->query(a->h - a->lant->varf->h+1,b->h- b->lant->varf->h+1));

            fprintf(out,"%d\n",act);

        }

    }
}

void gen_lant(int nod, int lant)
{
    if(nod==29800)
        nod=29800;
    if(l[lant].lengh==0)
    {
        l[lant].varf=&v[nod];
    }
    l[lant].lengh++;
    v[nod].lant=&l[lant];

    int who=0;

    for(int p=lst[nod]; p; p=nxt[p])
    {
        if(v[val[p]].lant==0)
        {
            if(v[val[p]].fii>v[who].fii)
                who=val[p];
        }
    }

    for(int p=lst[nod]; p; p=nxt[p])
    {
        if(v[val[p]].lant==0)
        {
            if(val[p]==who)
            {
                gen_lant(val[p],lant);
            }
            else
            {
                gen_lant(val[p],++last_lant);
            }
        }
    }

/*
    if(nxt[lst[nod]]==0)
    {
        if(lant==3414)
            lant=3414;


        l[lant].finise();
    }
*/
}

void nrfii(int nod, int tat)
{
    v[nod].fii=1;
    v[nod].tata=&v[tat];
    for(int p=lst[nod]; p; p=nxt[p])
    {
        if(val[p]!=tat)
        {
            v[val[p]].h=v[nod].h+1;
            nrfii(val[p],nod);
            v[nod].fii+=v[val[p]].fii;
        }
    }
}

void add(int a, int b)
{
    val[++nr]=b;
    nxt[nr]=lst[a];
    lst[a]=nr;
}

int main()
{
    fscanf(in,"%d%d",&n,&q);

    for(int i=1; i<=n; i++)
    {
        fscanf(in,"%d",&v[i].c);
    }

    int a,b;

    for(int i=1; i<n; i++)
    {
        fscanf(in,"%d%d",&a,&b);

        add(a,b);
        add(b,a);
    }

    v[1].h=1;

    nrfii(1,0);

    gen_lant(1,1);

    for(int i=1; i<=last_lant; i++)
        l[i].finise();

    for(int i=1; i<=n; i++)
    {
     //   l[v[i].lant].update(v[i].h-v[l[v[i].lant].varf].h+1,v[i].c);

        v[i].lant->update(v[i].h- v[i].lant->varf->h+1,v[i].c);
    }


    main2();

    return 0;
}