Cod sursa(job #2512859)

Utilizator Stefan_PiscuPiscu Stefan Constantin Stefan_Piscu Data 21 decembrie 2019 19:40:55
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.83 kb
#include <bits/stdc++.h>
using namespace std;

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

vector<int> heavy, head, ind, order, siz, level, fat, val;
vector<vector<int> >kids;
vector<vector<int>> vec;

void init(int n){
    vec.resize(n+1);
    val.resize(n+1, 0);
    ind.resize(n+1, 0);
    level.resize(n+1, 0);
    kids.resize(n+1);
    fat.resize(n+1, 0);
    siz.resize(n+1, 0);
    head.resize(n+1, 0);
    heavy.resize(n+1, 0);
    order.push_back(0);
}

bool viz[100002];

int n, m;

void dfs(int nod){
    viz[nod]=1;
    level[nod]=level[fat[nod]]+1;
    siz[nod]=1;
    for(auto i:vec[nod]){
        if(!viz[i]){
            fat[i]=nod;
            kids[nod].push_back(i);
            dfs(i);
            siz[nod]+=siz[i];
            if(siz[i]>siz[heavy[nod]]) heavy[nod]=i;
        }
    }
}

void decomp(int nod){
    if(!nod) return;
    ind[nod]=order.size();
    order.push_back(nod);
    if(heavy[nod]) head[heavy[nod]]=head[nod];
    decomp(heavy[nod]);
    for(auto i:kids[nod]){
        if(i!=heavy[nod]){
            head[i]=i;
            decomp(i);
        }
    }
}

int t[1000000];

void build(int st, int dr, int poz){
    if(st==dr) t[poz]=val[order[st]];
    else{
        int mid=(st+dr)/2;
        build(st, mid, poz*2);
        build(mid+1, dr, poz*2+1);
        t[poz]=max(t[poz*2], t[poz*2+1]);
    }
}

void update(int st, int dr, int poz, int val, int ind){
    if(st==dr) t[poz]=val;
    else{
        int mid=(st+dr)/2;
        if(mid>=ind) update(st, mid, poz*2, val, ind);
        else update(mid+1, dr, poz*2+1, val, ind);
        t[poz]=max(t[poz*2], t[poz*2+1]);
    }
}

int query(int st, int dr, int poz, int l, int r){
    if(l>r) return -1;
    if(l<=st&&dr<=r){
        return t[poz];
    }
    else{
        int mid=(st+dr)/2;
        return max(query(st, mid, poz*2, l, min(mid, r)), query(mid+1, dr, poz*2+1, max(mid+1, l), r));
    }
}

int query(int u, int v){
    if(level[u]>level[v]) swap(u, v);
    if(head[u]==head[v]){
        return query(1, n, 1, ind[u], ind[v]);
    }
    if(level[head[u]]>level[head[v]]){
        return max(query(1, n, 1, ind[head[u]], ind[u]), query(fat[head[u]], v));
    }
    else{
        return max(query(1, n, 1, ind[head[v]], ind[v]), query(fat[head[v]], u));
    }
}

int main()
{
    fin>>n>>m;
    init(n+1);
    for(int i=1;i<=n;++i){
        fin>>val[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);
    decomp(1);
    build(1, n, 1);
    for(int i=1;i<=m;++i){
        int t, u, v;
        fin>>t>>u>>v;
        if(t==1){
            fout<<query(u, v)<<"\n";
        }
        else{
            update(1, n, 1, v, ind[u]);
        }
    }
    return 0;
}