Cod sursa(job #3040876)

Utilizator hhhhhhhAndrei Boaca hhhhhhh Data 30 martie 2023 15:48:38
Problema Heavy Path Decomposition Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.17 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,m,val[100005],niv[100005],in[100005],out[100005],dp[18][100005];
vector<int> muchii[100005];
int where[100005],poz[100005];
int par[100005];
bool isheavy[100005];
int timp,nr[100005];
vector<vector<int>> arb;
vector<int> emp;
int path[100005],last[100005];
int lg[100005];
void dfs(int nod)
{
    timp++;
    in[nod]=timp;
    nr[nod]=1;
    dp[0][nod]=par[nod];
    for(int i=1;i<=17;i++)
        dp[i][nod]=dp[i-1][dp[i-1][nod]];
    for(int i:muchii[nod])
        if(i!=par[nod])
        {
            par[i]=nod;
            niv[i]=niv[nod]+1;
            dfs(i);
            nr[nod]+=nr[i];
        }
    out[nod]=timp;
    int who=0,maxim=0;
    for(int i:muchii[nod])
        if(i!=par[nod])
            if(nr[i]>maxim)
            {
                maxim=nr[i];
                who=i;
            }
    if(maxim>0)
        isheavy[who]=1;
}
void arbupdate(int ind,int nod,int st,int dr,int p,int x)
{
    if(st==dr)
    {
        arb[ind][nod]=x;
        return;
    }
    int mij=(st+dr)/2;
    if(p<=mij)
        arbupdate(ind,nod*2,st,mij,p,x);
    else
        arbupdate(ind,nod*2+1,mij+1,dr,p,x);
    arb[ind][nod]=max(arb[ind][nod*2],arb[ind][nod*2+1]);
}
int arbquery(int ind,int nod,int st,int dr,int a,int b)
{
    if(st>=a&&dr<=b)
        return arb[ind][nod];
    int mij=(st+dr)/2;
    int rez=0;
    if(a<=mij)
        rez=max(rez,arbquery(ind,nod*2,st,mij,a,b));
    if(b>mij)
        rez=max(rez,arbquery(ind,nod*2+1,mij+1,dr,a,b));
    return rez;
}
bool isancestor(int a,int b)
{
    return in[a]<=in[b]&&out[a]>=out[b];
}
int LCA(int a,int b)
{
    if(niv[a]>niv[b])
        swap(a,b);
    if(isancestor(a,b))
        return a;
    for(int i=17;i>=0;i--)
        if(dp[i][a]!=0&&!isancestor(dp[i][a],b))
            a=dp[i][a];
    return par[a];
}
void build()
{
    arb.push_back(emp);
    int cnt=0;
    for(int start=1;start<=n;start++)
    {
        bool good=1;
        for(int i:muchii[start])
            if(i!=par[start])
                if(isheavy[i])
                    good=0;
        if(good)
        {
            vector<int> pp;
            cnt++;
            arb.push_back(emp);
            int nod=start;
            while(true)
            {
                pp.push_back(nod);
                if(isheavy[nod])
                    nod=par[nod];
                else
                    break;
            }
            for(int i=0;i<pp.size();i++)
            {
                where[pp[i]]=cnt;
                poz[pp[i]]=i+1;
            }
            int lg=pp.size();
            path[cnt]=pp.size();
            last[cnt]=pp.back();
            arb[cnt].resize(3*lg+5);
        }
    }
}
void update(int nod,int val)
{
    int ind=where[nod];
    int p=poz[nod];
    arbupdate(ind,1,1,path[ind],p,val);
}
int query(int a,int lca)
{
    int rez=0;
    while(niv[a]>=niv[lca])
    {
        int ind=where[a];
        int p=poz[a];
        if(niv[last[ind]]>=niv[lca])
        {
            rez=max(rez,arbquery(ind,1,1,path[ind],p,path[ind]));
            a=par[last[ind]];
            continue;
        }
        else
        {
            int last=p+niv[a]-niv[lca];
            rez=max(rez,arbquery(ind,1,1,path[ind],p,last));
            break;
        }
    }
    return rez;
}
int main()
{
    ios_base::sync_with_stdio(false);
    fin.tie(0);
    fin>>n>>m;
    for(int i=1;i<=n;i++)
        fin>>val[i];
    for(int i=1;i<n;i++)
    {
        int a,b;
        fin>>a>>b;
        muchii[a].push_back(b);
        muchii[b].push_back(a);
    }
    niv[1]=1;
    dfs(1);
    build();
    for(int i=1;i<=n;i++)
        update(i,val[i]);
    while(m--)
    {
        int tip;
        fin>>tip;
        if(tip==0)
        {
            int nod,x;
            fin>>nod>>x;
            val[nod]=x;
            update(nod,x);
        }
        else
        {
            int a,b;
            fin>>a>>b;
            int lca=LCA(a,b);
            fout<<max(query(a,lca),query(b,lca))<<'\n';
        }
    }
    return 0;
}