Cod sursa(job #2682756)

Utilizator betybety bety bety Data 9 decembrie 2020 16:02:50
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.71 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
const int lim = 200001;
vector <int> v[lim];
int parent[lim];
int heavy[lim];
int lant[lim];
int lvl[lim];
int poz[lim];
int sz[lim];
int n,stamp;
class AINT
{
    int aint[4 * lim];
    void update(int node, int st, int dr, int poz, int val)
    {
        if(st == dr)
        {
            aint[node] = val;
            return;
        }
        int mid = (st + dr) / 2;
        if(poz <= mid)
            update(node * 2, st, mid, poz, val);
        else update(node * 2 + 1, mid + 1, dr, poz, val);
        aint[node] = max(aint[node * 2], aint[node * 2 + 1]);
    }
    int query(int node, int st, int dr, int a, int b)
    {
        if(a <= st and dr <= b)
            return aint[node];
        int mid = (st + dr) / 2;
        int maxim = 0;
        if(a <= mid) maxim = max(maxim, query(node * 2, st, mid, a, b));
        if(b > mid) maxim = max(maxim, query(node * 2 + 1, mid + 1, dr, a, b));
        return maxim;
    }
public:
    void u(int node, int val)
    {update(1, 1, n, poz[node], val);}
    int q(int l, int r)
    {
        if(poz[l] > poz[r]) swap(l, r);
        return query(1, 1, n, poz[l], poz[r]);
    }
} aint;
void dfs(int node, int p, int level)
{
    sz[node] = 1;
    int maxim = -1;
    parent[node] = p;
    lvl[node] = level;
    for(auto x : v[node])
    {
        if(x == p) continue;
        dfs(x, node, level + 1);
        sz[node] += sz[x];
        if(maxim == -1 or sz[x] > sz[maxim])
            maxim = x;
    }
    heavy[node] = maxim;
}
void heavy_traversal(int node, int p, int capat)
{
    poz[node] = ++stamp;
    lant[node] = capat;
    if(heavy[node] == -1) return;
    heavy_traversal(heavy[node], node, capat);
    for(auto x : v[node])
    {
        if(x == p or x == heavy[node]) continue;
        heavy_traversal(x, node, x);
    }
}
int query(int x, int y)
{
    int maxim = 0;
    while(lant[x] != lant[y])
    {
        if(lvl[lant[x]] < lvl[lant[y]]) swap(x, y);
        maxim = max(maxim, aint.q(x, lant[x]));
        x = parent[lant[x]];
    }
    maxim = max(maxim, aint.q(x, y));
    return maxim;
}
int a[lim];
int main()
{
    int i, m, x, y;
    in >> n >> m;
    for(i = 1; i <= n; i++)
        in>>a[i];
    for(i = 1; i < n; i++)
    {
        in >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1, 0, 0);
    heavy_traversal(1, 0, 1);
    for(i = 1; i <= n; i++)
        aint.u(i, a[i]);
    int t, a, b;
    while(m--)
    {
        in >> t >> a >> b;
        if(t == 0) aint.u(a, b);
        else out << query(a, b) << "\n";
    }
    return 0;
}