Cod sursa(job #2673128)

Utilizator vladth11Vlad Haivas vladth11 Data 15 noiembrie 2020 20:04:20
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.47 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define debug(x) cerr << #x << " " << x << "\n"
#define debug_with_space(x) cerr << #x << " " << x << " "

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair <ll, ll> pii;
typedef pair <ll, pii> piii;
typedef tree <pii, null_type, less <pii>, rb_tree_tag, tree_order_statistics_node_update> OST;

const ll NMAX = 200001;
const ll INF = 2e9;
const ll MOD = 1000000007;
const ll BLOCK = 101;
const ll nr_of_bits = 20;

int n;
int stamp = 0;
int poz[NMAX];
int sz[NMAX];
int heavy[NMAX];
int lant[NMAX];
int parent[NMAX];
int lvl[NMAX];
vector <int> v[NMAX];

class AINT{
    int aint[4 * NMAX];
    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 && 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 || 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 || 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[NMAX];

int main() {
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    int i, m;
    cin >> n >> m;
    for(i = 1; i <= n; i++){
        int x;
        cin >> x;
        a[i] = x;
    }
    for(i = 1; i < n; i++){
        int x, y;
        cin >> 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]);
    }
    while(m--){
        int t;
        cin >> t;
        int a, b;
        cin >> a >> b;
        if(t == 0){
            aint.u(a, b);
        }else{
            cout << query(a, b) << "\n";
        }
    }
    return 0;
}