Cod sursa(job #1396548)

Utilizator alex_bucevschiBucevschi Alexandru alex_bucevschi Data 22 martie 2015 17:54:43
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.81 kb
#include <bits/stdc++.h>
#define pb push_back
#define N 100005
using namespace std;
int gr[N],Tata[N],fg,niv[N],lant[N],cnt,poz[N],i,A[N],m,fs,y,x,a,b,sol,n,nn,t;
vector<int>v[N],p[N],arb[N];
void df(int nod,int tata)
{
    gr[nod]=1;
    int fg=0;
    for(auto fiu:v[nod])
    {
        if(fiu==tata)
            continue;
        Tata[fiu]=nod;
        niv[fiu]=niv[nod]+1;
        df(fiu,nod);
        gr[nod]+=gr[fiu];
        if(gr[fg]<gr[fiu])
            fg=fiu;
    }
    if(v[nod].size()==1&&nod!=1)
    {
        lant[nod]=++cnt;
        p[cnt].pb(0);
        p[cnt].pb(nod);
        poz[nod]=1;
        return;
    }
    lant[nod]=lant[fg];
    p[lant[nod]].pb(nod);
    poz[nod]=p[lant[nod]].size()-1;

}
void build(int nod,int l,int r)
{
    int m,fs;
    if(l==r)
    {
        arb[i][nod]=A[p[i][l]];
        return;
    }
    m=(l+r)/2;
    fs=2*nod;
    build(fs,l,m);
    build(fs+1,m+1,r);
    arb[i][nod]=max(arb[i][fs],arb[i][fs+1]);
}
void update(int nod,int l,int r)
{
    int m,fs;
    if(l==r)
    {
        arb[lant[x]][nod]=y;
        return;
    }
    m=(l+r)/2;
    fs=2*nod;
    if(poz[x]<=m)
        update(fs,l,m);
    else
        update(fs+1,m+1,r);
    arb[lant[x]][nod]=max(arb[lant[x]][fs],arb[lant[x]][fs+1]);
}
void query(int nod,int l,int r)
{
    int m,fs;
    if(a<=l&&r<=b)
    {
        sol=max(sol,arb[lant[x]][nod]);
        return;
    }
    if(a>r||b<l)
        return;
    m=(l+r)/2;
    fs=2*nod;
    query(fs,l,m);
    query(fs+1,m+1,r);
}
int main()
{
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        scanf("%d",&A[i]);
    for(i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        v[x].pb(y);
        v[y].pb(x);
    }
    niv[1]=1;
    df(1,0);
    for(i=1;i<=cnt;i++)
    {
        reverse(p[i].begin()+1,p[i].end());
        nn=p[i].size();
        arb[i].resize(4*nn+10);
        build(1,1,nn-1);
    }
    for(i=1;i<=n;i++)
        poz[i]=p[lant[i]].size()-poz[i];
    for(;m;m--)
    {
        scanf("%d%d%d",&t,&x,&y);
        if(t==0)
            update(1,1,p[lant[x]].size()-1);
        else
        {
            sol=0;
            for(;;)
            {
                if(lant[x]==lant[y])
                {
                    a=min(poz[x],poz[y]);
                    b=max(poz[x],poz[y]);
                    query(1,1,p[lant[x]].size()-1);
                    printf("%d\n",sol);
                    break;
                }
                if(niv[p[lant[x]][1]]<niv[p[lant[y]][1]])
                    swap(x,y);
                a=1;
                b=poz[x];
                query(1,1,p[lant[x]].size()-1);
                x=Tata[p[lant[x]][1]];
            }
        }
    }
    return 0;
}