Cod sursa(job #3156359)

Utilizator alexdumitruAlexandru Dumitru alexdumitru Data 11 octombrie 2023 12:10:45
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.23 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 100005;

int myMax(int &a, int &b)
{
    return a > b ? a : b;
}

int myMin(int &a, int &b)
{
    return a < b ? a : b;
}

void mySwap(int &a, int &b)
{
    int c = a;
    a = b;
    b = c;
}

struct SegTree {
    int *aint;
    int n;
    void init(int sz)
    {
        sz *= 4;
        aint = new int[sz + 1];
        memset(aint, 0, sizeof(aint));
    }
    int query(int nod, int st, int dr, int l, int r)
    {
        if(l <= st && dr <= r)
            return aint[nod];
        int mij = (st + dr) / 2;
        int v1 = 0, v2 = 0;
        if(l <= mij)
            v1 = query(nod * 2, st, mij, l, r);
        if(mij < r)
            v2 = query(nod * 2 + 1, mij + 1, dr, l, r);
        return myMax(v1, v2);
    }
    void update(int nod, int st, int dr, int poz, int val)
    {
        if(st == dr)
        {
            aint[nod] = val;
            return;
        }
        int mij = (st + dr) / 2;
        if(poz <= mij)
            update(nod * 2, st, mij, poz, val);
        else update(nod * 2 + 1, mij + 1, dr, poz, val);
        aint[nod] = myMax(aint[nod * 2], aint[nod * 2 + 1]);
    }
    ~SegTree()
    {
        delete[] aint;
    }
};



int n, q;
vector<int> g[NMAX];
int v[NMAX];

int lvl[NMAX];
int sz[NMAX];
int maxSon[NMAX];
int dad[NMAX];
int id[NMAX];
int pos[NMAX];
int csz[NMAX];
int chainBoss[NMAX];
int cnt;

SegTree chain[NMAX];

void getW(int nod, int tata)
{
    dad[nod] = tata;
    lvl[nod] = lvl[tata] + 1;
    sz[nod] = 1;
    for(auto it : g[nod])
        if(it != tata)
        {
            getW(it, nod);
            sz[nod] += sz[it];
            if(sz[it] > sz[maxSon[nod]])
                maxSon[nod] = it;
        }
}

void dfs(int nod)
{
    id[nod] = cnt;
    pos[nod] = ++csz[cnt];
    if(!maxSon[nod])
        return;
    dfs(maxSon[nod]);
    for(auto it : g[nod])
        if(it != dad[nod] && it != maxSon[nod])
        {
            chainBoss[++cnt] = it;
            dfs(it);
        }
}

int query(int x, int y)
{
    if(id[x] == id[y])
        return chain[id[x]].query(1, 1, csz[id[x]], myMin(pos[x], pos[y]), myMax(pos[x], pos[y]));
    if(lvl[chainBoss[id[x]]] < lvl[chainBoss[id[y]]])
        mySwap(x, y);
    return myMax(chain[id[x]].query(1, 1, csz[id[x]], 1, pos[x]), query(dad[chainBoss[id[x]]], y));
}

void update(int x, int y)
{
    chain[id[x]].update(1, 1, csz[id[x]], pos[x], y);
}

void solve()
{
    fin >> n >> q;
    for(int i = 1; i <= n; i++)
        fin >> v[i];
    for(int i = 1; i < n; i++)
    {
        int u, v;
        fin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    getW(1, 0);
    cnt = 1;
    chainBoss[1] = 1;
    dfs(1);
    for(int i = 1; i <= cnt; i++)
        chain[i].init(csz[i]);
    for(int i = 1; i <= n; i++)
        chain[id[i]].update(1, 1, csz[id[i]], pos[i], v[i]);
    while(q--)
    {
        int tip, x, y;
        fin >> tip >> x >> y;
        if(tip == 0)
            update(x, y);
        else fout << query(x, y) << '\n';
    }
}

int main()
{
    solve();
    return 0;
}