Cod sursa(job #2128138)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 11 februarie 2018 14:46:56
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.09 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");
list <int> arb[Nmax];
int t[Nmax],lvl[Nmax],nr_chain[Nmax],weight[Nmax],poz[Nmax],v[Nmax];
vector <int> chain[Nmax],Aint[Nmax];
int n,Q,N;
void DFS(int x)
{
    weight[x]=1;
    list <int> :: iterator it;
    int nod=0;
    bool is_leaf=true;
    for(it=arb[x].begin();it!=arb[x].end();++it)
        if(!lvl[*it])
        {
            is_leaf=false;
            lvl[*it]=lvl[x]+1;
            t[*it]=x;
            DFS(*it);
            if(weight[*it]>weight[nod]) nod=*it;
            weight[x]+=weight[*it];
        }
    if(is_leaf)
    {
        chain[++N].push_back(x);
        nr_chain[x]=N;
    }
    else
    {
        chain[nr_chain[nod]].push_back(x);
        nr_chain[x]=nr_chain[nod];
    }
}
int nr_arb,lsh,rsh,look_for,ans,val;
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,max1=-INT_MAX,max2=-INT_MAX;
        if(lsh<=m) max1=query(p,m,ls);
        if(m<rsh) max2=query(m+1,q,rs);
        return max(max1,max2);
    }
}
void heavy_path(int x, int y)
{
    ans=-INT_MAX;
    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];
        val=query(0,chain[nr_arb].size()-1,0);
        if(val>ans) ans=val;
        x=t[chain[nr_chain[x]][0]];
    }
    nr_arb=nr_chain[x];
    lsh=min(poz[x],poz[y]);
    rsh=poz[x]+poz[y]-lsh;
    val=query(0,chain[nr_arb].size()-1,0);
    if(val>ans) ans=val;
    g<<ans<<'\n';
}
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<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;
    int x,y;
    while(Q--)
    {
        f>>op>>x>>y;
        if(op)
        {
            heavy_path(x,y);
        }
        else
        {
            val=y;
            v[x]=y;
            nr_arb=nr_chain[x];
            look_for=poz[x];
            update(0,chain[nr_arb].size()-1,0);
        }
    }

    return 0;
}