Cod sursa(job #3041668)

Utilizator DordeDorde Matei Dorde Data 31 martie 2023 23:39:06
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.97 kb
#include<algorithm>
#include<fstream>
#include<vector>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int const N = 1e5 + 3;
int n , m , a , b;
int t[N] , d[N] , mx[N] , fiu[N] , sz[N] , val[N];
vector<int> v[N];
void dfs(int x , int tx = -1){
    sz[x] = 1;
    for(int y : v[x]){
        if(y == tx)
            continue;
        d[y] = 1 + d[x];
        t[y] = x;
        dfs(y , x);
        sz[x] += sz[y];
        if(sz[y] > sz[fiu[x]]){
            mx[x] = y;
            fiu[x] = y;
        }
    }
}
struct aint{
    int M;
    vector<int> t;
    aint(){}
    aint(int _M) : M(_M) , t(2 * M , 0){}
    void update(int p , int val){
        t[p += M - 1] = val;
        for(p >>= 1 ; p ; p >>= 1)
            t[p] = max(t[p * 2] , t[p * 2 + 1]);
    }
    int query(int l , int r){
        int res(0);
        for(l += M - 1 , r += M ; l < r ; l >>= 1 , r >>= 1){
            if(l & 1)
                res = max(res , t[l++]);
            if(r & 1)
                res = max(res , t[--r]);
        }
        return res;
    }
};
int rt[N] , l[N] , dl[N] , nrl;
vector<int> L[30];
inline int pos(int x){
    return d[x] - d[rt[l[x]]] + 1;
}
void dfs2(int x , int t = -1 , bool nou = true , int lnt = 1 , int adl = 0){
    if(nou){
        lnt = ++nrl;
        rt[lnt] = x;
    }
    dl[lnt] = adl;
    l[x] = lnt;
    L[lnt].push_back(x);
    for(int y : v[x]){
        if(y == t)
            continue;
        if(y == fiu[x])
            dfs2(y , x , false , lnt , adl);
        else
            dfs2(y , x , true , -1 , adl + 1);
    }
}
int root;
vector<aint> T;
int query(int x , int y){
    if(l[x] == l[y]){
        if(pos(x) > pos(y))
            swap(x , y);
        return T[l[x]].query(pos(x) , pos(y));
    }
    if(dl[l[x]] > dl[l[y]])
        swap(x , y);
    int res = 0;
    while(dl[l[y]] > dl[l[x]]){
        res = max(res , T[l[y]].query(1 , pos(y)));
        y = t[rt[l[y]]];
    }
    if(l[x] == l[y])
        return max(res , query(x , y));
    while(l[x] != l[y]){
        res = max(res , T[l[x]].query(1 , pos(x)));
        res = max(res , T[l[y]].query(1 , pos(y)));
        y = t[rt[l[y]]];
        x = t[rt[l[x]]];
    }
    return max(res , query(x , y));
}
int main(){
    fin >> n >> m;
    for(int i = 1 ; i <= n ; ++ i){
        fin >> val[i];
    }
    for(int i = 1 ; i < n ; ++ i){
        fin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    dfs(1);
    dfs2(1);
    T.push_back(aint());
    for(int i = 1 ; i <= nrl ; ++ i){
        aint nt(L[i].size());
        for(int j = 0 ; j < L[i].size() ; ++ j)
            nt.update(j + 1 , val[L[i][j]]);
        T.push_back(nt);
    }
    for(int i = 1 ; i <= m ; ++ i){
        int tp , x , y;
        fin >> tp >> x >> y;
        if(tp){
            fout << query(x , y) << '\n';
        }else{
            T[l[x]].update(pos(x) , y);
        }

    }
    return 0;
}