Cod sursa(job #1428357)

Utilizator heracleRadu Muntean heracle Data 4 mai 2015 11:30:13
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.61 kb
#include <cstdio>

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

const int Q=200007;

struct node;

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

int partitie[7*Q];

struct arbore
{
    int mg;

    void change(int p, int st, int dr, int poz, int val)
    {
        if(st==dr)
        {
            partitie[mg+p]=val;
            return;
        }

        int md=(st+dr)/2;

        if(poz<=md)
        {
            change(p*2,st,md,poz,val);
        }
        else
        {
            change(p*2+1,md+1,dr,poz,val);
        }

        partitie[mg+p]=maxim(partitie[mg+2*p],partitie[mg+2*p+1]);
    }

    int give(int p, int st, int dr, int a, int b)
    {
        if(st>b || dr<a)
            return 0;
        if(st>=a && dr<=b)
            return partitie[mg+p];

        int md=(st+dr)/2;

        return maxim(give(2*p,st,md,a,b),give(2*p+1,md+1,dr,a,b));
    }
};

struct lant
{
    node *varf;
    int size;
    arbore a;

    void update(int poz, int val)
    {
        a.change(1,1,size, poz, val);
    }

    int ask(int st, int dr)
    {
        return a.give(1,1,size,st,dr);
    }

}l[Q];

int nxtl=1;

struct node
{
    int fii;
    int h;
    node *tata;
    lant *l;
} v[Q];

void query(int x, int y)
{
    int rez=0;

    node *a=&v[x],*b=&v[y];

    while(a->l!=b->l)
    {
        if(a->l->varf->tata->h  >  b->l->varf->tata->h)
        {
            rez=maxim(rez,a->l->ask(1,a->h - a->l->varf->h+1));

            a=a->l->varf->tata;
        }
        else
        {
            rez=maxim(rez,b->l->ask(1,b->h - b->l->varf->h+1));

            b=b->l->varf->tata;
        }
    }
    if(a->h > b->h)
        rez=maxim(rez,a->l->ask(b->h - b->l->varf->h+1 , a->h - a->l->varf->h+1));
    else
        rez=maxim(rez,a->l->ask(a->h - a->l->varf->h+1, b->h - b->l->varf->h+1));

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

}


int cost[Q];

int n,q;

int lastpart;

void main2()
{
    for(int i=1; i<=nxtl; i++)
    {
        l[i].a.mg=lastpart;
        lastpart+=5*l[i].size;
    }

    for(int i=1; i<=n; i++)
    {
        v[i].l->update(v[i].h-v[i].l->varf->h+1  ,cost[i]);
    }

    int t,x,y;

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

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

    }


}


///------------------make lant




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

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




void dfs2(int nod, int tata, int lt)
{
    if(l[lt].size==0)
    {
        l[lt].varf=&v[nod];
    }
    l[lt].size++;
    v[nod].l=&l[lt];

    int max=0;
    for(int p=lst[nod]; p; p=nxt[p])
    {
        if(val[p]!=tata)
        {
            if(v[max].fii<v[val[p]].fii)
                max=val[p];
        }
    }

    for(int p=lst[nod]; p; p=nxt[p])
    {
        if(val[p]!=tata)
        {
            if(max==val[p])
                dfs2(val[p], nod, lt);
            else
                dfs2(val[p], nod, ++nxtl);
        }
    }

}




void dfs1(int nod, int tata)
{
    v[nod].fii=1;
    v[nod].h=v[tata].h+1;
    v[nod].tata=&v[tata];

    for(int p=lst[nod]; p; p=nxt[p])
    {
        if(val[p]!=tata)
        {
            dfs1(val[p],nod);
            v[nod].fii+=v[val[p]].fii;
        }
    }
}


///------------------make lant


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

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

    int a,b;

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

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

    dfs1(1,0);
    dfs2(1,0,1);

    main2();

    return 0;
}