Cod sursa(job #3245959)

Utilizator Robert_MitriRobert Mitri Robert_Mitri Data 1 octombrie 2024 11:44:32
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int nmax = 100000;

vector <int> v[nmax + 5];

int a[4*nmax + 5];
int val[nmax + 5];
int sz[nmax + 5];
int hv[nmax + 5];
int idd[nmax + 5];
int t[nmax + 5];
int lv[nmax + 5];
int r[nmax + 5];
int inv[nmax + 5];
int n,m;
int o;
void df1(int nod)
{
    sz[nod]=1;
    lv[nod]=lv[t[nod]]+1;
    for(auto& i : v[nod]){
        if(t[nod]==i) continue;
        t[i]=nod;
        df1(i);
        sz[nod]+=sz[i];
        if(sz[i] > sz[hv[nod]])
            hv[nod] = i;
    }
}
void build(int nod,int st,int dr)
{
    if(st==dr) {a[nod] = val[inv[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 x)
{
    if(st==dr) {a[nod] = x; return;}
    int mid = (st+dr)/2;
    if(poz<=mid) update(nod*2,st,mid,poz,x);
    else update(nod*2+1,mid+1,dr,poz,x);
    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 s1=0,s2=0;
    if(x<=mid) s1 = query(nod*2,st,mid,x,y);
    if(y>mid) s2 = query(nod*2+1,mid+1,dr,x,y);
    return max(s1,s2);
}
void mk(int nod,int head)
{
    r[nod] = head;
    idd[nod]=++o;
    inv[o]=nod;
    if(hv[nod])
        mk(hv[nod],head);
    for(auto& i : v[nod]) if(i!=t[nod] && i!=hv[nod]) mk(i,i);
}
int query_path(int x,int y)
{
    int sol = 0;
    while(r[x]!=r[y])
    {
        if(lv[r[x]] > lv[r[y]]) swap(x,y);
        sol=max(sol,query(1,1,n,idd[r[y]],idd[y]));
        y=t[r[y]];
    }
    if(lv[x] > lv[y]) swap(x,y);
    sol=max(sol,query(1,1,n,idd[x],idd[y]));
    return sol;
}


int main()
{
    fin>>n>>m;
    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);
    }
    df1(1);
    mk(1,1);
    build(1,1,n);


    for(int i=1;i<=m;i++)
    {
        int t;
        fin>>t;
        if(t==0)
        {
            int x,y;
            fin>>x>>y;
            update(1,1,n,idd[x],y);
        }
        else
        {
            int x,y;
            fin>>x>>y;
            fout<<query_path(x,y)<<'\n';
        }
    }
}