Cod sursa(job #3204652)

Utilizator aaagabiTurbinca Gabriel aaagabi Data 17 februarie 2024 11:17:46
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.81 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
vector <int> vec[100005];
int n,m;
int v[100005];
int tata[100005],depth[100005];
int cap[100005],vals[100005],desc[100005];
int heavy[100005];
int aint[400005];
int dfs(int nod,int par)
{
    int cursize=1;
    int maxval=-1;
    for(auto x:vec[nod])
        if(x!=par)
    {
        tata[x]=nod;
        depth[x]=depth[nod]+1;
        int newval=dfs(x,nod);
        cursize+=newval;
        if(newval>maxval)
        {
            maxval=newval;
            heavy[nod]=x;
        }
    }
    return cursize;
}
int poz;
void hld(int head,int nod)
{
    vals[nod]=++poz;
    cap[nod]=head;
    if(heavy[nod])
        hld(head,heavy[nod]);
    for(auto x:vec[nod])
    {
        if(x!=heavy[nod]&&x!=tata[nod])
        hld(x,x);
    }
}
void build(int nod,int st,int dr)
{
    if(st==dr)
    {
        aint[nod]=desc[st];
    }
    else
    {
        int mid=(st+dr)/2;
        build(2*nod,st,mid);
        build(2*nod+1,mid+1,dr);
        aint[nod]=max(aint[2*nod],aint[2*nod+1]);
    }
}
void update(int nod,int st,int dr,int poz,int val)
{
    if(st==dr)
    {
        aint[nod]=val;
    }
    else
    {
        int mid=(st+dr)/2;
        if(poz<=mid)
            update(2*nod,st,mid,poz,val);
        else
            update(2*nod+1,mid+1,dr,poz,val);
        aint[nod]=max(aint[2*nod],aint[2*nod+1]);
    }
}
int aintquery(int nod,int st,int dr,int ql,int qr)
{
    if(ql>qr)
        return 0;
    if(st==ql&&dr==qr)
        return aint[nod];
    else
    {
        int mid=(st+dr)/2;
        return max(aintquery(2*nod,st,mid,ql,min(mid,qr)),aintquery(2*nod+1,mid+1,dr,max(ql,mid+1),qr));
    }
}
int query(int x,int y)
{
    int ans=0;
    while(cap[x]!=cap[y])
    {
        if(depth[cap[x]]>depth[cap[y]])
            swap(x,y);
        ans=max(ans,aintquery(1,1,n,vals[cap[y]],vals[y]));
        y=tata[cap[y]];
    }
    if(vals[x]>vals[y])
        swap(x,y);
    ans=max(ans,aintquery(1,1,n,vals[x],vals[y]));
    return ans;
}
int main()
{
    fin>>n>>m;
    for(int i=1;i<=n;i++)
        fin>>v[i];
    for(int i=1;i<n;i++)
    {
        int x,y;
        fin>>x>>y;
        vec[x].push_back(y);
        vec[y].push_back(x);
    }
    dfs(1,0);
    hld(1,1);
    for(int i=1;i<=n;i++)
    {
        desc[vals[i]]=v[i];
    }
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        int t,x,y;
        fin>>t>>x>>y;
        if(t==0)
        {
            update(1,1,n,vals[x],y);
            desc[vals[x]]=y;
            /*for(int j=1;j<=n;j++)
                fout<<desc[j]<<' ';
            fout<<'\n';*/
        }
        if(t==1)
        {
            fout<<query(x,y)<<'\n';
        }
    }
    return 0;
}