Cod sursa(job #1522130)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 11 noiembrie 2015 11:39:42
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include <bits/stdc++.h>
#define Nmax 100005
#define INF 2000000000
#define pb push_back

using namespace std;

int n,val[Nmax],nr[Nmax],Lant[Nmax],Father[Nmax],cnt,Len[Nmax],Poz[Nmax],lvl[Nmax];
vector <int> L[Nmax],v[Nmax];

class ST
{
public :
    vector <int> aint;
    inline void upd(int nod, int st, int dr, int p, int val)
    {
        if(st==dr)
        {
            aint[nod]=val; return;
        }
        int mij=((st+dr)>>1);
        if(p<=mij) upd(2*nod,st,mij,p,val);
        else upd(2*nod+1,mij+1,dr,p,val);
        aint[nod]=max(aint[2*nod],aint[2*nod+1]);
    }
    inline int qry(int nod, int st, int dr, int x, int y)
    {
        if(st==x && y==dr) return aint[nod];
        int mij=((st+dr)>>1);
        if(y<=mij) return qry(2*nod,st,mij,x,y);
        else
            if(x>mij) return qry(2*nod+1,mij+1,dr,x,y);
            else
                return max(qry(2*nod,st,mij,x,mij),qry(2*nod+1,mij+1,dr,mij+1,y));
    }
} Trees[Nmax];

inline void Dfs(int nod, int tata, int niv)
{
    vector <int> ::iterator it;
    nr[nod]=1; lvl[nod]=niv;
    int node=0;
    for(it=L[nod].begin();it!=L[nod].end();++it)
    {
        if(*it==tata) continue;
        Dfs(*it,nod,niv+1); nr[nod]+=nr[*it];
        if(!node || nr[node]<nr[*it]) node=*it;
    }
    if(!node)
    {
        Lant[nod]=++cnt; Poz[nod]=1;
    }
    else
    {
        Lant[nod]=Lant[node]; Poz[nod]=Poz[node]+1;
    }
    for(it=L[nod].begin();it!=L[nod].end();++it)
        if(*it!=tata && *it!=node) Father[Lant[*it]]=nod;
    ++Len[Lant[nod]];
    v[Lant[nod]].pb(val[nod]);
}

inline void Build_Trees()
{
    for(int i=1;i<=cnt;++i)
    {
        Trees[i].aint.resize(4*Len[i]);
        for(int j=0;j<v[i].size();++j) Trees[i].upd(1,1,Len[i],j+1,v[i][j]);
    }
}

int main()
{
    int i,m,x,y,tip;
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    cin>>n>>m;
    for(i=1;i<=n;++i) cin>>val[i];
    for(i=1;i<n;++i)
    {
        cin>>x>>y; L[x].pb(y); L[y].pb(x);
    }
    Dfs(1,0,0);
    Build_Trees();
    while(m--)
    {
        cin>>tip>>x>>y;
        if(tip)
        {
            int sol=-INF;
            while(Lant[x]!=Lant[y])
            {
                if(lvl[Father[Lant[x]]] < lvl[Father[Lant[y]]]) swap(x,y);
                sol=max(sol,Trees[Lant[x]].qry(1,1,Len[Lant[x]],Poz[x],Len[Lant[x]]));
                x=Father[Lant[x]];
            }
            sol=max(sol,Trees[Lant[x]].qry(1,1,Len[Lant[x]],min(Poz[x],Poz[y]),max(Poz[x],Poz[y])));
            cout<<sol<<"\n";
        }
        else Trees[Lant[x]].upd(1,1,Len[Lant[x]],Poz[x],y);
    }
    return 0;
}