Cod sursa(job #1644396)

Utilizator touristGennady Korotkevich tourist Data 9 martie 2016 22:55:34
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.66 kb
#include <bits/stdc++.h>
#define Nmax 100005
#define pb push_back

using namespace std;

int val[Nmax],Nivel[Nmax],cnt[Nmax],Wh[Nmax],Father[Nmax];
int cntLant,poz[Nmax],n;
vector <int> L[Nmax],Lanturi[Nmax];

class Aint
{
public:
    vector <int> aint;
    inline void upd(int nod, int st, int dr, int p, int x)
    {
        if(st==dr)
        {
            aint[nod]=x; return;
        }
        int mij=((st+dr)>>1);
        if(p<=mij) upd(2*nod,st,mij,p,x);
        else upd(2*nod+1,mij+1,dr,p,x);
        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));
    }
} Lant[Nmax];

inline void Dfs(int nod, int tata)
{
    int node=0;
    cnt[nod]=1;
    for(auto it : L[nod])
    {
        if(it==tata) continue;
        Nivel[it]=Nivel[nod]+1;
        Dfs(it,nod);
        if(cnt[it]>cnt[node]) node=it;
        cnt[nod]+=cnt[it];
    }
    if(!node)
    {
        Wh[nod]=++cntLant;
        Lanturi[cntLant].pb(nod);
        poz[nod]=1;
        return;
    }
    Wh[nod]=Wh[node];
    Lanturi[Wh[node]].pb(nod);
    poz[nod]=poz[node]+1;
    for(auto it : L[nod])
    {
        if(it==tata || it==node) continue;
        Father[Wh[it]]=nod;
    }
}

inline void Initialize()
{
    int i,j;
    for(i=1;i<=cntLant;++i)
    {
        Lant[i].aint.resize(4*Lanturi[i].size()+2);
        for(j=0;j<Lanturi[i].size();++j)
            Lant[i].upd(1,1,Lanturi[i].size(),j+1,val[Lanturi[i][j]]);
    }
}

int main()
{
    int i,t,x,y,m;
    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);
    }
    Nivel[1]=1; Dfs(1,0);
    Initialize();
    while(m--)
    {
        cin>>t>>x>>y;
        if(!t) Lant[Wh[x]].upd(1,1,Lanturi[Wh[x]].size(),poz[x],y);
        else
        {
            int sol=0;
            while(Wh[x]!=Wh[y])
            {
                if(Nivel[Father[Wh[x]]]<Nivel[Father[Wh[y]]]) swap(x,y);
                sol=max(sol,Lant[Wh[x]].qry(1,1,Lanturi[Wh[x]].size(),poz[x],Lanturi[Wh[x]].size()));
                x=Father[Wh[x]];
            }
            sol=max(sol,Lant[Wh[x]].qry(1,1,Lanturi[Wh[x]].size(),min(poz[x],poz[y]),max(poz[x],poz[y])));
            cout<<sol<<"\n";
        }
    }
    return 0;
}