Cod sursa(job #2845906)

Utilizator vmnechitaNechita Vlad-Mihai vmnechita Data 8 februarie 2022 15:25:34
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.29 kb
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pf push_front
#define MOD 1000000007
#define MAX 100005

using namespace std;

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


int val[MAX], arb[4*MAX];

vector < int > v[MAX], ind;
int n, nvl[MAX], t[MAX], heavy[MAX], radacina_heavy_path[MAX], coresp[MAX], r;

void dfs(int nod, int prec);
int set_heavy(int nod);
void set_arbint(int nod);
void rezolva(int u, int v);

void construieste(int nod, int st, int dr)
{
    int mij;

    if(st == dr) arb[nod] = val[ind[st]];
    else
    {
        mij = (st + dr) / 2;
        construieste(2 * nod, st, mij);
        construieste(2 * nod + 1, mij + 1, dr);
        arb[nod] = max(arb[2*nod], arb[2*nod+1]);
    }
}

void update(int nod, int st, int dr, int poz, int val)
{
    int mij;

    if(st == dr) arb[nod] = val;
    else
    {
        mij = (st + dr) / 2;
        if(poz <= mij) update(2 * nod, st, mij, poz, val);
        else update(2 * nod + 1, mij + 1, dr, poz, val);
        arb[nod] = max(arb[2*nod], arb[2*nod+1]);
    }
}

int query(int nod, int st, int dr, int x, int y)
{
    int mij;

    if(x <= st && y >= dr) return arb[nod];
    else
    {
        mij = (st + dr) / 2;
        if(x > mij) return query(2 * nod + 1, mij + 1, dr, x, y);
        else if(y <= mij) return query(2 * nod, st, mij, x, y);
        else return max(query(2 * nod + 1, mij + 1, dr, x, y), query(2 * nod, st, mij, x, y));
    }
}


int main()
{
    int q, i, x, y, t;

    fin >> n >> q;
    for(i = 1; i <= n; i++) fin >> val[i];
    for(i = 1; i < n; i++) fin >> x >> y, v[x].pb(y), v[y].pb(x);

    dfs(1, 0);
    for(i = 1; i <= n; i++) radacina_heavy_path[i] = i;
    set_heavy(1), ind.pb(0), set_arbint(1);
    construieste(1, 1, n);

    while(q--)
    {
        fin >> t >> x >> y;
        if(t == 0) update(1, 1, n, coresp[x], y);
        else
        {
            r = 0;
            rezolva(x, y);
            fout << r << '\n';
        }
    }


    return 0;
}

void dfs(int nod, int prec)
{
    nvl[nod] = nvl[prec] + 1, t[nod] = prec;
    for(auto it:v[nod]) if(nvl[it] == 0) dfs(it, nod);
}

int set_heavy(int nod)
{
    int s = 1, x, maxx = 0;

    for(auto it:v[nod])
        if(it != t[nod])
        {
            x = set_heavy(it);
            s += x;
            if(x > maxx) maxx = x, heavy[nod] = it;
        }

    if(heavy[nod] != 0) radacina_heavy_path[heavy[nod]] = radacina_heavy_path[nod];

    return s;
}

void set_arbint(int nod)
{
    ind.pb(nod), coresp[nod] = ind.size() - 1;
    if(heavy[nod] != 0) set_arbint(heavy[nod]);
    for(auto it:v[nod]) if(it != t[nod] && it != heavy[nod]) set_arbint(it);
}

void rezolva(int u, int v)
{
    int x = radacina_heavy_path[u], y = radacina_heavy_path[v], z;
    if(x == y)
    {
        z = query(1, 1, n, min(coresp[u], coresp[v]), max(coresp[u], coresp[v]));
        r = max(r, z);
    }
    else if(nvl[x] >= nvl[y])
    {
        z = query(1, 1, n, min(coresp[u], coresp[x]), max(coresp[u], coresp[x]));
        r = max(r, z);
        rezolva(t[x], v);
    }
    else
    {
        z = query(1, 1, n, min(coresp[v], coresp[y]), max(coresp[v], coresp[y]));
        r = max(r, z);
        rezolva(u, t[y]);
    }
}