Cod sursa(job #3216615)

Utilizator AndreibatmanAndrei Croitoriu Andreibatman Data 18 martie 2024 18:05:31
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.59 kb
#include <bits/stdc++.h>
#define NMAX 100010
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int heavy[NMAX],lv[NMAX],poz[NMAX],head[NMAX],tree[4*NMAX],tata[NMAX],euler[NMAX],val[NMAX];
vector<int>v[NMAX];
int n,q,lg;
void build(int node,int left,int right)
{
    if(left==right)
    {
        tree[node]=val[euler[left]];
        return;
    }
    int mij=(left+right)/2;
    build(2*node,left,mij);
    build(2*node+1,mij+1,right);
    tree[node]=max(tree[2*node],tree[2*node+1]);
}
void update(int node,int left,int right,int pos,int val)
{
    if(left==right)
    {
        tree[node]=val;
        return;
    }
    int mij=(left+right)/2;
    if(pos<=mij)
        update(2*node,left,mij,pos,val);
    else
        update(2*node+1,mij+1,right,pos,val);
    tree[node]=max(tree[2*node],tree[2*node+1]);
}
int query(int node,int left,int right,int st,int dr)
{
    if(st<=left && right<=dr)
        return tree[node];
    int mij=(left+right)/2,a=0,b=0;
    if(st<=mij)
        a=query(2*node,left,mij,st,dr);
    if(mij<dr)
        b=query(2*node+1,mij+1,right,st,dr);
    return max(a,b);
}
int dfs(int node,int parent)
{
    lv[node]=lv[parent]+1;
    tata[node]=parent;
    int total=1,maxi=0;
    for(auto it:v[node])
        if(it!=parent)
        {
            int cnt=dfs(it,node);
            total+=cnt;
            if(cnt>maxi)
                maxi=cnt,heavy[node]=it;
        }
    return total;
}
void create_path(int node,int cap,int parent)
{
    head[node]=cap;
    euler[++lg]=node;
    poz[node]=lg;
    if(heavy[node]!=0)
        create_path(heavy[node],cap,node);
    for(auto it:v[node])
        if(it!=parent && it!=heavy[node])
            create_path(it,it,node);
}
int query_hld(int a,int b)
{
    int maxi=0;
    while(head[a]!=head[b])
    {
        if(lv[head[a]]>lv[head[b]])
            swap(a,b);
        maxi=max(maxi,query(1,1,n,poz[head[b]],poz[b]));
        b=tata[head[b]];
    }
    if(lv[a]>lv[b])
        swap(a,b);
    maxi=max(maxi,query(1,1,n,poz[a],poz[b]));
    return maxi;
}
int main()
{
    fin>>n>>q;
    for(int i=1;i<=n;i++)
        fin>>val[i];
    for(int i=1;i<n;i++)
    {
        int x,y;
        fin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1,0);
    create_path(1,1,0);
    build(1,1,n);
    while(q--)
    {
        int t,x,y;
        fin>>t>>x>>y;
        ///cout<<x<<" "<<y<<'\n';
        if(t==0)
            update(1,1,n,poz[x],y);
        else
            fout<<query_hld(x,y)<<'\n';
    }
    return 0;
}