Cod sursa(job #1147684)

Utilizator tudgal1001Profir Tudor tudgal1001 Data 20 martie 2014 01:51:28
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.47 kb
#include<algorithm>
#include<cstdio>
#include<vector>
#define NMax 100010
using namespace std;

int val[NMax],niv[NMax],SubArb[NMax];
int nrL,N,lantTata[NMax],lantNiv[NMax];
int arbInt[4*NMax],arbPoz[NMax];
int lantDim[NMax],lant[NMax];
vector<int> Vc[NMax],L[NMax];

void DF (int nod)
{
    int bestFiu=-1,okFr=1;
    SubArb[nod]=1;
    for (vector<int>::iterator it=Vc[nod].begin(); it!=Vc[nod].end(); ++it)
        if (!niv[*it])
        {
            niv[*it]=niv[nod]+1;
            okFr=0;
            DF(*it);
            SubArb[nod]+=SubArb[*it];
            if (bestFiu==-1)
                bestFiu=(*it);
            else if (SubArb[*it]>SubArb[bestFiu])
                bestFiu=(*it);
        }
    if (okFr)
    {
        lant[nod]=++nrL;
        lantDim[nrL]=1;
        L[nrL].push_back(nod);
    }
    else
    {
        lant[nod]=lant[bestFiu];
        lantDim[lant[nod]]++;
        L[lant[nod]].push_back(nod);
        for (vector<int>::iterator it=Vc[nod].begin(); it!=Vc[nod].end(); ++it)
            if ((*it)!=bestFiu && niv[*it]>niv[nod])
            {
                lantTata[lant[*it]]=nod;
                lantNiv[lant[*it]]=niv[nod];
            }
    }
}

void build (int nod, int st, int dr, int decj, int lant)
{
    if (st==dr)
    {
        arbInt[nod+decj]=val[L[lant][st-1]];
        return;
    }
    int mid=(st+dr)/2;
    build(2*nod,st,mid,decj,lant);
    build(2*nod+1,mid+1,dr,decj,lant);
    arbInt[nod+decj]=max(arbInt[2*nod+decj],arbInt[2*nod+1+decj]);
}

void update (int nod, int st, int dr, int poz, int vall, int decj)
{
    if (st==dr)
    {
        arbInt[nod+decj]=vall;
        return;
    }
    int mid=(st+dr)/2;
    if (poz<=mid)
        update(2*nod,st,mid,poz,vall,decj);
    else
        update(2*nod+1,mid+1,dr,poz,vall,decj);
    arbInt[nod+decj]=max(arbInt[2*nod+decj],arbInt[2*nod+1+decj]);
}

int query (int nod, int st, int dr, int a, int b, int decj)
{
    if (a<=st && dr<=b)
        return arbInt[nod+decj];
    int mid=(st+dr)/2,rez=0;
    if (a<=mid)
        rez=max(rez,query(2*nod,st,mid,a,b,decj));
    if (mid<b)
        rez=max(rez,query(2*nod+1,mid+1,dr,a,b,decj));
    return rez;
}

int main ()
{
    int i,tip,x,y,M,sol;
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);
    scanf("%d%d",&N,&M);
    for (i=1; i<=N; i++)
        scanf("%d",&val[i]);
    for (i=1; i<N; i++)
    {
        scanf("%d%d",&x,&y);
        Vc[x].push_back(y);
        Vc[y].push_back(x);
    }
    niv[1]=1;
    DF(1);
    for (i=1; i<=nrL; i++)
    {
        reverse(L[i].begin(),L[i].end());
        arbPoz[i]=arbPoz[i-1]+4*lantDim[i-1];
        build(1,1,lantDim[i],arbPoz[i],i);
    }
    for (i=1; i<=M; i++)
    {
        scanf("%d%d%d",&tip,&x,&y);
        if (!tip)
            update(1,1,lantDim[lant[x]],niv[x]-lantNiv[lant[x]],y,arbPoz[lant[x]]);
        else
        {
            sol=0;
            while (1)
            {
                if (lant[x]==lant[y])
                {
                    if (niv[x]>niv[y])
                        swap(x,y);
                    sol=max(sol,query(1,1,lantDim[lant[x]],niv[x]-lantNiv[lant[x]],
                            niv[y]-lantNiv[lant[y]],arbPoz[lant[x]]));
                    break;
                }
                if (lantNiv[lant[x]]<lantNiv[lant[y]])
                    swap(x,y);
                sol=max(sol,query(1,1,lantDim[lant[x]],1,niv[x]-lantNiv[lant[x]],arbPoz[lant[x]]));
                x=lantTata[lant[x]];
            }
            printf("%d\n",sol);
        }
    }
    return 0;
}