Cod sursa(job #3196834)

Utilizator Robert_MitriRobert Mitri Robert_Mitri Data 24 ianuarie 2024 20:49:53
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.54 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define sz 100000
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

int heavy[sz + 5];
int lv[sz + 5];
int pos[sz + 5];
int head[sz + 5];
int a[4*sz + 5];
int pr[sz + 5];
int pp[sz + 5];
vector <int> v[sz + 5];
int val[sz + 5];
int n,q;

int o;


void build(int nod,int st,int dr)
{
    if(st==dr)
    {
        a[nod] = val[pp[st]];
        return;
    }
    int mid = (st+dr)/2;
    build(nod*2,st,mid);
    build(nod*2+1,mid+1,dr);
    a[nod]=max(a[nod*2],a[nod*2+1]);
}
void update(int nod,int st,int dr,int poz,int val)
{
    if(st==dr)
    {
        a[nod]=val;
        return;
    }
    int mid = (st+dr)/2;
    if(poz<=mid)
        update(nod*2,st,mid,poz,val);
    else
        update(nod*2+1,mid+1,dr,poz,val);
    a[nod]=max(a[nod*2],a[nod*2+1]);
}
int query(int nod,int st,int dr,int x,int y)
{
    if(x<=st && dr<=y)
        return a[nod];
    int mid = (st+dr)/2;
    int a=0;int b=0;
    if(x <= mid)
        a = query(nod*2,st,mid,x,y);
    if (y>mid)
        b = query(nod*2+1,mid+1,dr,x,y);
    return max(a,b);
}
int dfs(int nod,int t)
{
    lv[nod]=lv[t]+1;
    pr[nod]=t;
    int sz_tot = 1;
    int mx_sz = 0;
    for(auto& i : v[nod])
        if(i!=t)
        {
            int rez = dfs(i,nod);
            sz_tot+=rez;
            if(rez > mx_sz)
                mx_sz = rez,heavy[nod] = i;
        }
    return sz_tot;
}
void create_path(int nod,int hd,int t)
{
    head[nod]=hd;
    ++o;
    pp[o]=nod;
    pos[nod]=o;
    if(heavy[nod])
        create_path(heavy[nod],hd,nod);
    for(auto& i : v[nod])
        if(i!=t && i!=heavy[nod])
            create_path(i,i,nod);
}

int path_query(int a,int b)
{
    int sol = 0;
    while(head[a]!=head[b])
    {
        if(lv[head[a]]>lv[head[b]])
            swap(a,b);
        sol = max(sol,query(1,1,n,pos[head[b]],pos[b]));
        b=pr[head[b]];
    }
    if(lv[a]>lv[b])
        swap(a,b);
    sol=max(sol,query(1,1,n,pos[a],pos[b]));
    return sol;
}


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);
    for(int i=1;i<=q;i++)
    {
        int t,x,y;
        fin>>t>>x>>y;
        if(t==0)
            update(1,1,n,pos[x],y);
        else
            fout<<path_query(x,y)<<'\n';
    }

}