Cod sursa(job #2817596)

Utilizator loraclorac lorac lorac Data 13 decembrie 2021 21:40:51
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.19 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
const int lim=1e5+4;
struct lant
{
    vector<int> tree;
    vector<int> v;
    lant* tata;
    int vf;
    void build(int nod,int l,int r)
    {
        if(l==r)
        {
            tree[nod]=v[l];
            return ;
        }
        int med=(l+r)>>1;
        build(2*nod,l,med);
        build(2*nod+1,med+1,r);
        tree[nod]=max(tree[2*nod],tree[2*nod+1]);
    }
    void update(int nod,int l,int r,int poz)
    {
        if(l==r)
        {
            tree[nod]=v[l];
            return ;
        }
        int med=(l+r)>>1;
        if(poz<=med) update(2*nod,l,med,poz);
        else update(2*nod+1,med+1,r,poz);
        tree[nod]=max(tree[2*nod],tree[2*nod+1]);
    }
    int query(int nod,int l,int r,int a,int b)
    {
        if(a<=l and r<=b)
            return tree[nod];
        int med=(l+r)>>1;
        int ans1=0,ans2=0;
        if(a<=med) ans1=query(2*nod,l,med,a,b);
        if(b>med) ans2=query(2*nod+1,med+1,r,a,b);
        return max(ans1,ans2);
    }
};
vector<int> vec[lim];
lant* casa[lim];
bool viz[lim];
int papa[lim];
int ind[lim];
int add[lim];
int val[lim];
int dim[lim];
int n,q,t,x,y;
void df(int nod)
{
    dim[nod]=1;
    viz[nod]=true;
    for(int x:vec[nod])
    if(!viz[x])
    {
        add[x]=add[nod]+1;
        df(x);
        papa[x]=nod;
        dim[nod]+=dim[x];
    }
}
void df2(int nod)
{
    int maxim=0,unde=0;
    for(int x:vec[nod])
    if(x!=papa[nod])
    {
        if(dim[x]>=maxim)
            maxim=dim[x],
            unde=x;
    }
    if(unde==0)
        return ;
    casa[unde]=casa[nod];
    ind[unde]=casa[unde]->v.size();
    casa[unde]->v.push_back(val[unde]);
    df2(unde);
    for(int x:vec[nod])
    if(x!=papa[nod] and x!=unde)
    {
        casa[x]=new lant();
        casa[x]->vf=x;
        ind[x]=casa[x]->v.size();
        casa[x]->tata=casa[nod];
        casa[x]->v.push_back(val[x]);
        df2(x);
        casa[x]->tree.resize(4*casa[x]->v.size());
        casa[x]->build(1,0,casa[x]->v.size()-1);
    }
}
int main()
{
    in>>n>>q;
    for(int i=1;i<=n;++i)
        in>>val[i];
    for(int i=1;i<n;++i)
        in>>x>>y,
        vec[x].push_back(y),
        vec[y].push_back(x);
    df(1);
    casa[1]=new lant();
    casa[1]->vf=1;
    ind[1]=casa[1]->v.size();
    casa[1]->v.push_back(val[1]);
    df2(1);
    casa[1]->tree.resize(4*casa[1]->v.size());
    casa[1]->build(1,0,casa[1]->v.size()-1);
    while(q--)
    {
        in>>t>>x>>y;
        if(t==0)
        {
            casa[x]->v[ind[x]]=y;
            casa[x]->update(1,0,casa[x]->v.size()-1,ind[x]);
            continue;
        }
        int maxim=0;
        while(casa[x]->vf!=casa[y]->vf)
        {
            if(add[casa[x]->vf]<add[casa[y]->vf])
                swap(x,y);
            maxim=max(maxim,casa[x]->query(1,0,casa[x]->v.size()-1,0,ind[x]));
            x=papa[casa[x]->vf];
        }
        if(ind[x]>ind[y])
            swap(x,y);
        maxim=max(maxim,casa[x]->query(1,0,casa[x]->v.size()-1,ind[x],ind[y]));
        out<<maxim<<'\n';
    }
    return 0;
}