Cod sursa(job #2986678)

Utilizator CReaper1116Shang Cheng Lin CReaper1116 Data 28 februarie 2023 21:54:12
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.87 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int N = 100000,logn = 17;
int v[N],sub[N],cnt = 0,cnt2 = 0;
int endpoint[N],n;
int dpth[N];
vector<int> e[N];
int parent[logn][N];
int hp[N],v2[N],v3[N],seg[4*N];
void dfs(int node,int p = -1,int d = 0){
    sub[node] = 1;
    dpth[node] = d;
    parent[0][node] = (p == -1?node:p);
    for(auto i:e[node]){
        if(i == p)continue;
        dfs(i,node,d + 1);
        sub[node]+=sub[i];
    }
    bool ok = 0;
    for(auto i:e[node]){
        if(i == p)continue;
        if(sub[node]/2 <= sub[i]){
            ///heavy
            ok = 1;
            hp[node] = hp[i];
            break;
        }
    }
    if(!ok){
        ///new component
        hp[node] = cnt++;
    }
}
void dfs2(int node,int p = -1){
    if(p != -1 && hp[p] == hp[node]){
        endpoint[node] = endpoint[p];
    }else{
        endpoint[node] = node;
    }
    v2[node] = cnt2++;
    for(auto i:e[node]){
        if(i == p)continue;
        if(hp[i] == hp[node]){
            dfs2(i,node);
        }
    }
    for(auto i:e[node]){
        if(i == p)continue;
        if(hp[i] != hp[node]){
            dfs2(i,node);
        }
    }
}
int lca(int a,int b){
    if(dpth[a] < dpth[b]){
        swap(a,b);
    }
    for(int i = logn - 1;i >= 0;i--){
        if(dpth[a] - (1<<i) >= dpth[b]){
            a = parent[i][a];
        }
    }
    for(int i = logn - 1;i >= 0;i--){
        if(parent[i][a] != parent[i][b]){
            a = parent[i][a];
            b = parent[i][b];
        }
    }
    if(a != b){
        return parent[0][a];
    }else return a;
}
void build(int l,int r,int node = 1){
    if(l == r){
        seg[node] = v3[l];
    }else{
        int mij = (l + r)/2;
        build(l,mij,node*2);
        build(mij + 1,r,node*2 + 1);
        seg[node] = max(seg[node*2],seg[node*2 + 1]);
    }
}
void modify(int target,int nr,int l,int r,int node = 1){
    if(l == r){
        v3[target] = nr;
        seg[node] = nr;
    }else{
        int mij = (l + r)/2;
        if(target <= mij){
            modify(target,nr,l,mij,node*2);
        }else{
            modify(target,nr,mij + 1,r,node*2 + 1);
        }
        seg[node] = max(seg[node*2],seg[node*2 + 1]);
    }
}
int query(int l2,int r2,int l,int r,int node = 1){
    if(l2 > r2)swap(l2,r2);
    //if(l == 0 && r == n - 1)fout<<l2<<' '<<r2<<'\n';
    int nr = 0;
    if(l2 <= l && r <= r2){
        nr = seg[node];
    }else{
        int mij = (l + r)/2;
        if(l2 <= mij)nr = max(nr,query(l2,r2,l,mij,node*2));
        if(mij + 1 <= r2)nr = max(nr,query(l2,r2,mij + 1,r,node*2 + 1));
    }
    return nr;
}
int query2(int node,int p){
    int ans = 0;
    if(hp[node] != hp[p]){
        ///node -> endpoint
        ans = query(v2[node],v2[endpoint[node]],0,n - 1);
        ans = max(ans,query2(parent[0][endpoint[node]],p));
    }else{
        ///node -> c
        ans = query(v2[node],v2[p],0,n - 1);
    }
    return ans;
}
int main(){
    int q,i,j,u,w,cer,a,b;
    fin>>n>>q;
    for(i = 0;i < n;i++){
        fin>>v[i];
    }
    for(i = 0;i < n - 1;i++){
        fin>>u>>w;
        u--;w--;
        e[u].push_back(w);
        e[w].push_back(u);
    }
    dfs(0);
    dfs2(0);
    for(i = 1;i < logn;i++){
        for(j = 0;j < n;j++){
            parent[i][j] = parent[i - 1][parent[i - 1][j]];
        }
    }
    for(i = 0;i < n;i++){
        v3[v2[i]] = v[i];
    }
    build(0,n - 1);
    for(i = 0;i < q;i++){
        fin>>cer>>a>>b;
        a--;b--;
        if(cer == 1){
            int c = lca(a,b);
            fout<<max(query2(a,c),query2(b,c))<<'\n';;
        }else{
            b++;
            modify(a,b,0,n - 1);
        }
        //for(j = 0;j < n;j++)fout<<v3[j]<<' ';
        //fout<<'\n';
    }
    return 0;
}