Cod sursa(job #2188100)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 26 martie 2018 22:17:04
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.93 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 v[Nmax],nr_chain[Nmax],weight[Nmax],t[Nmax],lvl[Nmax],poz[Nmax];
list <int> arb[Nmax];
vector <int> Aint[Nmax],chain[Nmax];
int n,Q,N,lsh,rsh,nr_arb,look_for;
void DFS(int x)
{
    bool is_leaf=true;
    int node=0;
    weight[x]=1;
    for(const auto &it:arb[x])
        if(!lvl[it])
        {
            is_leaf=false;
            lvl[it]=lvl[x]+1;
            t[it]=x;
            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];
    }
}
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]=v[chain[nr_arb][p]];
    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 solve_query(int x, int y)
{
    int 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);
        lsh=0;
        rsh=poz[x];
        nr_arb=nr_chain[x];
        ans=max(ans,query(0,chain[nr_arb].size()-1,0));
        x=t[chain[nr_arb][0]];
    }
    lsh=min(poz[x],poz[y]);
    rsh=max(poz[x],poz[y]);
    nr_arb=nr_chain[x];
    ans=max(ans,query(0,chain[nr_arb].size()-1,0));
    return ans;
}
int main()
{
    int i,j,k;
    bool op;
    f>>n>>Q;
    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);
    }
    while(Q--)
    {
        f>>op>>i>>j;
        if(!op)
        {
            v[i]=j;
            nr_arb=nr_chain[i];
            look_for=poz[i];
            update(0,chain[nr_arb].size()-1,0);
        }
        else g<<solve_query(i,j)<<'\n';
    }

    return 0;
}