Cod sursa(job #2886783)

Utilizator pctirziuTirziu Petre pctirziu Data 8 aprilie 2022 12:27:03
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.09 kb
#include <fstream>
#include <vector>

using namespace std;
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
const int nmax = 1e5 + 5;
int maxx = 0;
int n;
vector <int> edge[nmax];
int v[nmax], invliniarizare[nmax], depth[nmax], parent[nmax], stsize[nmax], head[nmax];
vector <int> liniarizare;
int aint[4 * nmax];
void aint_update(int node, int st, int dr, int poz, int val)
{
    if(st == dr){
        aint[node] = val;
        return ;
    }
    int med = (st + dr) / 2;
    if(poz <= med)
        aint_update(2 * node, st, med, poz, val);
    else
        aint_update(2 * node + 1, med + 1, dr, poz, val);
    aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}
int aint_query(int node, int st, int dr, int gst, int gdr)
{
    if(gst == st and gdr == dr)
        return aint[node];
    int med = (st + dr) / 2;
    if(gst > med)
        return aint_query (2 * node + 1, med + 1, dr, gst, gdr);
    if(gdr <= med)
        return aint_query (2 * node, st, med, gst, gdr);
    return max(aint_query(2 * node, st, med, gst, med), aint_query(2 * node + 1, med + 1, dr, med + 1, gdr));
}
void update(int a, int val)
{
    aint_update(1, 1, n, invliniarizare[a], val);
}
int query(int a, int b)
{
    if(head[a] == head[b]){
        if(depth[a] > depth[b])
            swap(a, b);
        return aint_query(1, 1, n, invliniarizare[a], invliniarizare[b]);
    }
    if(depth[head[a]] > depth[head[b]])
        swap(a, b);
    return max(aint_query(1, 1, n, invliniarizare[head[b]], invliniarizare[b]), query(parent[head[b]], a));
}
void dfs(int node, int tata)
{
    stsize[node] = 1;
    depth[node] = depth[tata] + 1;
    parent[node] = tata;
    for(int i = 0; i < edge[node].size(); i++){
        int fiu = edge[node][i];
        if(fiu == tata)
            continue;
        dfs(fiu, node);
        stsize[node] += stsize[fiu];
    }
}
void decompose(int node, int cnt_head)
{
    head[node] = cnt_head;
    liniarizare.push_back(node);
    invliniarizare[node] = liniarizare.size();
    int heavy = 0;
    for(int i = 0; i < edge[node].size(); i++)
        if(edge[node][i] != parent[node] and stsize[edge[node][i]] > stsize[heavy])
            heavy = edge[node][i];
    if(!heavy)
        return ;
    decompose(heavy, cnt_head);
    for(int i = 0; i < edge[node].size(); i++)
        if(edge[node][i] != parent[node] and edge[node][i] != heavy)
            decompose(edge[node][i], edge[node][i]);
}
int main()
{
    int i, j, q;
    cin >> n >> q;
    for(i = 1; i <= n; i++)
        cin >> v[i];
    for(i = 1; i <= n - 1; i++){
        int x, y;
        cin >> x >> y;
        edge[x].push_back(y);
        edge[y].push_back(x);
    }
    dfs(1, 1);
    decompose(1, 1);
    for(i = 1; i <= n; i++){
        if(i == 3)
            int x;
        aint_update(1, 1, n, invliniarizare[i], v[i]);
    }
    for(i = 1; i <= q; i++){
        int t, a, b;
        cin >> t >> a >> b;
        if(t == 0)
            update(a, b);
        else{
            maxx = 0;
            cout << query(a, b) << "\n";
        }
    }
    return 0;
}