Cod sursa(job #2178947)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 19 martie 2018 20:36:03
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.98 kb
#include <bits/stdc++.h>
#define Nmax 100005
#define ls (((nod+1)<<1)-1)
#define rs (ls+1)
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int n,Q,N;
list <int> arb[Nmax];
int v[Nmax],t[Nmax],lvl[Nmax],nr_chain[Nmax],poz[Nmax],weight[Nmax];
vector <int> chain[Nmax],Aint[Nmax];
void DFS(int x)
{
    int node=0;
    bool is_leaf=true;
    weight[x]=1;
    for(const auto &it:arb[x])
        if(!lvl[it])
        {
            lvl[it]=lvl[x]+1;
            t[it]=x;
            is_leaf=false;
            DFS(it);
            if(weight[it]>weight[node]) node=it;
            weight[x]+=weight[it];
        }
    if(is_leaf)
    {
        chain[++N].push_back(x);
        nr_chain[x]=N;
    }
    else
    {
        chain[nr_chain[node]].push_back(x);
        nr_chain[x]=nr_chain[node];
    }
}
int nr_arb,lsh,rsh,look_for,val,ans,aux;
void build(int p, int q, int nod)
{
    if(p==q) Aint[nr_arb][nod]=v[chain[nr_arb][p]];
    else
    {
        int m=(p+q)>>1;
        build(p,m,ls);
        build(m+1,q,rs);
        Aint[nr_arb][nod]=max(Aint[nr_arb][ls],Aint[nr_arb][rs]);
    }
}
void update(int p, int q, int nod)
{
    if(p==q) Aint[nr_arb][nod]=val;
    else
    {
        int m=(p+q)>>1;
        if(look_for<=m) update(p,m,ls);
        else update(m+1,q,rs);
        Aint[nr_arb][nod]=max(Aint[nr_arb][ls],Aint[nr_arb][rs]);
    }
}
int query(int p, int q, int nod)
{
    if(lsh<=p and q<=rsh) return Aint[nr_arb][nod];
    else
    {
        int m=(p+q)>>1,m1=INT_MIN,m2=INT_MIN;
        if(lsh<=m) m1=query(p,m,ls);
        if(m<rsh) m2=query(m+1,q,rs);
        return max(m1,m2);
    }
}
int heavy_path(int x, int y)
{
    ans=INT_MIN;
    while(nr_chain[x]!=nr_chain[y])
    {
        if(lvl[chain[nr_chain[x]][0]]<lvl[chain[nr_chain[y]][0]])
            swap(x,y);
        nr_arb=nr_chain[x];
        lsh=0;
        rsh=poz[x];
        aux=query(0,chain[nr_arb].size()-1,0);
        if(aux>ans) ans=aux;
        x=t[chain[nr_chain[x]][0]];
    }
    nr_arb=nr_chain[x];
    lsh=min(poz[x],poz[y]);
    rsh=poz[x]+poz[y]-lsh;
    aux=query(0,chain[nr_arb].size()-1,0);
    if(aux>ans) ans=aux;
    return ans;
}
int main()
{
    f>>n>>Q;
    int i,j,k;
    for(i=1;i<=n;i++)
        f>>v[i];
    for(k=1;k<n;k++)
    {
        f>>i>>j;
        arb[i].push_back(j);
        arb[j].push_back(i);
    }
    lvl[1]=1;
    DFS(1);
    for(k=1;k<=N;k++)
    {
        reverse(chain[k].begin(),chain[k].end());
        for(i=0;i<(int)chain[k].size();i++)
            poz[chain[k][i]]=i;
        Aint[k].resize(4*chain[k].size());
        nr_arb=k;
        build(0,chain[k].size()-1,0);
    }
    bool op;
    while(Q--)
    {
        f>>op>>i>>j;
        if(op)
            g<<heavy_path(i,j)<<'\n';
        else
        {
            val=j;
            nr_arb=nr_chain[i];
            look_for=poz[i];
            update(0,chain[nr_arb].size()-1,0);
        }
    }

    return 0;
}