Cod sursa(job #1301109)

Utilizator george_stelianChichirim George george_stelian Data 25 decembrie 2014 16:33:32
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.14 kb
#include <cstdio>
#include <vector>
#include <cstring>

using namespace std;

vector<int> v[100010],arb[100010];
int val[100010],sizesubarb[100010],niv[100010],lant[100010],poz[100010],sizelant[100010],firstnod[100010],tata[100010];
int nrlant,poz1,val1,lant1,left,right,sol;
char vaz[100010];

void dfs1(int nod)
{
    vaz[nod]=sizesubarb[nod]=1;
    for(vector<int>::iterator it=v[nod].begin();it!=v[nod].end();it++)
        if(!vaz[*it])
        {
            niv[*it]=niv[nod]+1;
            dfs1(*it);
            sizesubarb[nod]+=sizesubarb[*it];
        }
}

void dfs2(int nod,int l)
{
    vaz[nod]=1;
    lant[nod]=l;
    poz[nod]=++sizelant[l];
    int maxsubarb=0,heavyfiu=0;
    for(vector<int>::iterator it=v[nod].begin();it!=v[nod].end();it++)
        if(!vaz[*it] && sizesubarb[*it]>maxsubarb)
        {
            maxsubarb=sizesubarb[*it];
            heavyfiu=*it;
        }
    if(heavyfiu) dfs2(heavyfiu,l);
    for(vector<int>::iterator it=v[nod].begin();it!=v[nod].end();it++)
        if(!vaz[*it])
        {
            nrlant++;
            firstnod[nrlant]=*it;
            tata[nrlant]=nod;
            dfs2(*it,nrlant);
        }
}

void update(int nod,int st,int dr)
{
    if(st==dr)
    {
        arb[lant1][nod]=val1;
        return;
    }
    if(poz1<=(st+dr)/2) update(nod*2,st,(st+dr)/2);
    else update(nod*2+1,(st+dr)/2+1,dr);
    arb[lant1][nod]=max(arb[lant1][nod*2],arb[lant1][nod*2+1]);
}

void query(int nod,int st,int dr)
{
    if(left<=st && dr<=right)
    {
        sol=max(sol,arb[lant1][nod]);
        return;
    }
    if(left<=(st+dr)/2) query(nod*2,st,(st+dr)/2);
    if((st+dr)/2+1<=right) query(nod*2+1,(st+dr)/2+1,dr);
}

int main()
{
    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);
    int n,m,x,y,t;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&val[i]);
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs1(1);
    memset(vaz,0,sizeof(vaz));
    ++nrlant;
    firstnod[nrlant]=1;
    dfs2(1,nrlant);
    for(int i=1;i<=nrlant;i++) arb[i].resize(4*sizelant[i]);
    for(int i=1;i<=n;i++)
    {
        poz1=poz[i];
        val1=val[i];
        lant1=lant[i];
        update(1,1,sizelant[lant1]);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&t,&x,&y);
        if(!t)
        {
            poz1=poz[x];
            val1=y;
            lant1=lant[x];
            update(1,1,sizelant[lant1]);
        }
        else
        {
            int rez=0;
            while(lant[x]!=lant[y])
            {
                if(niv[firstnod[lant[x]]]<niv[firstnod[lant[y]]]) swap(x,y);
                sol=0;lant1=lant[x];left=1;right=poz[x];
                query(1,1,sizelant[lant1]);
                rez=max(rez,sol);
                x=tata[lant[x]];
            }
            left=poz[x];right=poz[y];lant1=lant[x];sol=0;
            if(left>right) swap(left,right);
            query(1,1,sizelant[lant1]);
            rez=max(rez,sol);
            printf("%d\n",rez);
        }
    }
    return 0;
}