Cod sursa(job #1721358)

Utilizator refugiatBoni Daniel Stefan refugiat Data 25 iunie 2016 13:52:03
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.73 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
ifstream si("heavypath.in");
ofstream so("heavypath.out");

const int MAXN=100005;
vector<int> v[MAXN],arb[MAXN];
int val[MAXN],s[MAXN],niv[MAXN],lant[MAXN],lp[MAXN],ls[MAXN],lt[MAXN],nlant;
void dfs(int nod,int tata,int lvl)
{
    s[nod]=1;
    niv[nod]=lvl;
    vector<int>::iterator i;
    for(i=v[nod].begin();i!=v[nod].end();++i)
        if(*i!=tata)
        {
            dfs(*i,nod,lvl+1);
            s[nod]+=s[*i];
        }
}
void dfs1(int nod,int tata,int l)
{
    lant[nod]=l;
    ++ls[l];
    lp[nod]=ls[l];
    int h=0;
    vector<int>::iterator i;
    for(i=v[nod].begin();i!=v[nod].end();++i)
    {
        if(*i!=tata&&s[*i]>s[h])
            h=*i;
    }
    if(!h)
        return;
    dfs1(h,nod,l);
    for(i=v[nod].begin();i!=v[nod].end();++i)
    {
        if(*i!=tata&&*i!=h)
        {
            ++nlant;
            lt[nlant]=nod;
            dfs1(*i,nod,nlant);
        }
    }
}
void update(int nod,int st,int dr,int poz,int val,vector<int>&arb)
{
    if(st==dr)
    {
        arb[nod]=val;
        return;
    }
    int mid=(st+dr)>>1;
    if(poz<=mid)
        update(nod*2,st,mid,poz,val,arb);
    else
        update(nod*2+1,mid+1,dr,poz,val,arb);
    arb[nod]=max(arb[nod*2],arb[nod*2+1]);
}
int query(int nod,int st,int dr,int qs,int qd,vector<int> &arb)
{
    if(qs<=st&&qd>=dr)
        return arb[nod];
    int mid=(st+dr)/2,sol=0;
    if(qs<=mid)
    {
        sol=max(sol,query(nod*2,st,mid,qs,qd,arb));
    }
    if(qd>mid)
    {
        sol=max(sol,query(nod*2+1,mid+1,dr,qs,qd,arb));
    }
    return sol;
}
int main()
{
    int n,m,x,y,q;
    si>>n>>m;
    int i;
    for(i=1;i<=n;i++)
        si>>val[i];
    for(i=1;i<n;++i)
    {
        si>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1,0,1);
    //cout<<1;
    nlant=1;
    dfs1(1,0,nlant);
    for(i=1;i<=nlant;++i)
        arb[i].resize(ls[i]*4);
    //cout<<1;
    for(i=1;i<=n;++i)
    {
        update(1,1,ls[lant[i]],lp[i],val[i],arb[lant[i]]);
    }
    for(i=1;i<=m;++i)
    {
        si>>q>>x>>y;
        if(q==0)
            update(1,1,ls[lant[x]],lp[x],y,arb[lant[x]]);
        else
        {
            int sol=0;
            while(lant[x]!=lant[y])
            {
                if(niv[lt[lant[x]]]<niv[lt[lant[y]]])
                    swap(x,y);
                sol=max(sol,query(1,1,ls[lant[x]],1,lp[x],arb[lant[x]]));
                x=lt[lant[x]];
            }
            if(lp[x]>lp[y])
                swap(x,y);
            sol=max(sol,query(1,1,ls[lant[x]],lp[x],lp[y],arb[lant[x]]));
            so<<sol<<'\n';
        }
    }
    return 0;
}