Cod sursa(job #3130626)

Utilizator Botnaru_VictorBotnaru Victor Botnaru_Victor Data 18 mai 2023 10:24:18
Problema Heavy Path Decomposition Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.52 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("heavypath.in");
ofstream g("heavypath.out");

const int MN = 1e5+5;
const int MB = 20;

int n,q;
vector<int> adj[MN];
int par[MB][MN];
int h[MN], lcap[MN], l[MN], lk;
int hcop[MN];
int siz[MN];
int v[MN];

void initdfs(int nod)
{
    for(int i=1;i<MB;i++)
    {
        par[i][nod]=par[i-1][par[i-1][nod]];
    }
    
    h[nod]=h[par[0][nod]]+1;
    siz[nod]=1;
    
    
    int mx=0;
    for(auto e:adj[nod]) if(e!=par[0][nod])
    {
        par[0][e]=nod;
        initdfs(e);
        siz[nod]+=siz[e];
        
        if(siz[e]>siz[mx]) mx=e;
    }
    
    if(mx==0)
    {
        l[nod]=++lk;
        lcap[lk]=nod;
    }
    else
    {
        l[nod]=l[mx];
        lcap[l[nod]]=nod;
    }
    
    hcop[nod]=mx;
}


int lca(int a, int b)
{
    if(h[a]<h[b]) swap(a,b);
    
    for(int i=MB-1;i>=0;i--)
    {
        if(h[ par[i][a] ]>=h[b]) a=par[i][a];
    }
    
    if(a==b) return a;
    
    for(int i=MB-1;i>=0;i--)
    {
        if(par[i][a]!=par[i][b]) a=par[i][a], b=par[i][b];
    }
    return par[0][a];
}

int arbint[MN*2];
int apoz[MN], ak;

void arbintup(int up, int uv)
{
    for( arbint[up+=n] = uv; up>1; up>>=1)
    {
        arbint[up>>1]= max(arbint[up], arbint[up^1]);
    }
}

int arbintquery(int qst, int qdr)
{
    int ans=0;
    for(qst+=n, qdr+=n; qst<qdr; qst>>=1, qdr>>=1)
    {
        if (qst&1) ans=max(ans, arbint[qst++]);
        if (qdr&1) ans=max(ans, arbint[--qdr]);
    }
    return ans;
}

void arbintdfs(int nod)
{
    arbintup(ak, v[nod]);
    apoz[nod]=ak++;
    
    
    if(hcop[nod]!=0)
    {
        arbintdfs(hcop[nod]);
    }
    
    for(auto e:adj[nod]) if(par[0][nod]!=e&&hcop[nod]!=e)
    {
        arbintdfs(e);
    }
}

int doquery(int a, int b)
{
    int c=lca(a,b);
    
    int ans=0;
    for(int i=0;i<2;i++)
    {
        while(l[a]!=l[c])
        {
            ans=max(ans, arbintquery( apoz[ lcap[ l[a] ] ], apoz[ a ] +1 ) );
            a=par[0][ lcap[ l[a] ] ];
        }
        ans=max( ans, arbintquery(apoz[ c ], apoz[ a ]+1 ) );
        swap(a,b);
    }
    return ans;
}


int main()
{
    f>>n>>q;
    int a,b,c;
    for(int i=1;i<=n;i++)
    {
        f>>v[i];
    }
    
    for(int i=1;i<n;i++)
    {
        f>>a>>b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    
    initdfs(1);
    arbintdfs(1);
    
    for(int i=1;i<=q;i++)
    {
        f>>a>>b>>c;
        if(a==0)
        {
            arbintup(apoz[b],c);
        }
        else
        {
            g<<doquery(b, c)<<'\n';
        }
    }

    return 0;
}