Cod sursa(job #3273478)

Utilizator Simon2712Simon Slanina Simon2712 Data 2 februarie 2025 13:12:00
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.44 kb
#include <fstream>
#include <vector>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");


const int N = 1e5;
struct nod{
    int val, heavy, p, head, time;
} v[N + 1];
vector<int> muc[N + 1];

int n, q;
void read(){
    fin>>n>>q;
    for(int i = 1; i <= n; i++)
        fin>>v[i].val;
    for(int i = 1; i < n; i++)
    {
        int a, b;
        fin>>a>>b;
        muc[a].push_back(b);
        muc[b].push_back(a);
    }
}

int find_heavy(int nod){
    int sz_max = 0, sz_tot = 1;
    for(auto fiu:muc[nod])
        if(fiu != v[nod].p && !v[fiu].p)
        {
            v[fiu].p = nod;
            int sz = find_heavy(fiu);
            if(sz > sz_max) sz_max = sz, v[nod].heavy = fiu;
            sz_tot += sz;
        }
    return sz_tot;
}

int timp = 0;
void decompose(int nod, int head){
    timp++;
    v[nod].head = head;
    v[nod].time = timp;
    if(v[nod].heavy)    decompose(v[nod].heavy, head);
    for (auto fiu:muc[nod])
        if(fiu != v[nod].p && fiu != v[nod].heavy)
            decompose(fiu, fiu);
}

int aint[2 * N];
void create_aint(){
    for(int i = 1; i <= n; i++)
        aint[v[i].time + n - 1] = v[i].val;
    for(int i = n - 1; i > 0; i--)
        aint[i] = max(aint[2 * i], aint[2 * i + 1]);
}

void upd(int x, int y){
    x = x + n - 1;
    aint[x] = y;
    for(x/=2; x; x>>=1)
        aint[x] = max(aint[2 * x], aint[2 * x + 1]);

}

int rmq(int l, int r){
    l += n - 1;
    r += n - 1;
    int maxi = 0;
    while(l <= r){
        if(l % 2 == 1){
            maxi = max(maxi, aint[l]);
            l++;
        }
        l = l / 2;
        if(r % 2 == 0){
            maxi = max(maxi, aint[r]);
            r--;
        }
        r = r / 2;
    }
    return maxi;
}

int query(int x, int y){
    int ans = 0;
    while(v[x].head != v[y].head){
        if(v[x].time < v[y].time)
            swap(x, y);
        ans = max(ans, rmq(v[v[x].head].time, v[x].time));
        x = v[v[x].head].p;
    }
    if(v[x].time < v[y].time)
        swap(x, y);
    ans = max(ans, rmq(v[y].time, v[x].time));
    return ans;
}

void queries(){
    while(q--){
        int tip, x, y;
        fin>>tip>>x>>y;
        if(tip == 0)
            upd(x, y);
        else
            fout<<query(x, y)<<'\n';
    }
}
int main()
{
    read();
    find_heavy(1);
    decompose(1, 1);
    create_aint();
    queries();
    return 0;
}