Cod sursa(job #2588192)

Utilizator Mirela_MagdalenaCatrina Mirela Mirela_Magdalena Data 24 martie 2020 15:58:04
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.59 kb
#define NMAX 100005
#include <fstream>
#include <vector>
using namespace std;

ifstream f("heavypath.in");
ofstream g("heavypath.out");

int n, m, a, b, idxl = 1, iddfs = 1, t, added;
int valori[NMAX], tati[NMAX], interv[NMAX], adancime[NMAX], subarbore[NMAX];
int label_lant[NMAX], idfs[NMAX];
vector<int> graph[NMAX];


void dfs(int nod, int tata, int nivel)
{
    tati[nod] = tata;
    adancime[nod] = nivel;
    subarbore[nod] = 1;

    for(auto &v:graph[nod])
        if(v != tata)
        {
            dfs(v, nod, nivel+1);
            subarbore[nod] += subarbore[v];
        }
}

vector<int> orddfs;
void form_labels(int nod, int tata, int labelact)
{
    idfs[nod] = iddfs++;
    label_lant[nod] = labelact;
    orddfs.push_back(nod);
    int biggest_child = -1;

    for(auto &v:graph[nod])
        if(v != tata)
        {
            if(biggest_child == -1 || (biggest_child != -1 && subarbore[v] > subarbore[biggest_child]))
                biggest_child = v;
        }
    if(biggest_child != -1)
    {
        form_labels(biggest_child, nod, labelact);
    }
    for(auto &v:graph[nod])
        if(v != biggest_child && v != tata)
            form_labels(v, nod, v);
}






void afis(int a[])
{
    for(int i = 1; i <= n; ++i)
        g<<a[i]<<" ";
    g<<'\n';
}


void form_interv(int poz_inter, int st, int dr, int val, int poz)
{
    if(st == dr)
    {
        interv[poz_inter] = val;
        return;
    }
    int mijl = (st + dr)/2;
    if(poz <= mijl)
        form_interv(2*poz_inter, st, mijl, val, poz);
    else
        form_interv(2*poz_inter + 1, mijl+1, dr, val, poz);
    interv[poz_inter] = max(interv[2*poz_inter], interv[2*poz_inter + 1]);
}


int query(int pozint, int sti, int dri, int st, int dr)
{
    if(st <= sti && dri <= dr)
        return interv[pozint];
    int mijl = (sti + dri)/2;
    int val1 = -1, val2 = -1;
    if(mijl >= dr)
    {
        val1 = query(2*pozint, sti, mijl, st, dr);
    }
    else if(mijl <= st)
    {
        val2 = query(2*pozint+1, mijl+1, dri, st, dr);
    }
    else{
        val1 = query(2*pozint, sti, mijl, st, dr);
        val2 = query(2*pozint+1, mijl, dri, st, dr);
    }
    return max(val1, val2);
}






int findmax(int x, int y)
{
    if(label_lant[x] == label_lant[y])
    {
        if(idfs[x] > idfs[y])
            swap(x, y);
        return query(1, 1, n, idfs[x], idfs[y]);
    }
    else{
        if(label_lant[x] < label_lant[y])
            swap(x, y);
        return max(query(1, 1, n, idfs[label_lant[x]], idfs[x]), findmax(tati[label_lant[x]], y));
    }
}



void update(int nod, int st, int dr, int indexv, int with)
{
    if(st == dr)
    {
        interv[nod] = with;
        return;
    }
    int mijl = (st + dr)/2;
    if(indexv <= mijl)
        update(2*nod, st, mijl, indexv, with);
    else update(2*nod+1, mijl+1, dr, indexv, with);
    interv[nod] = max(interv[2*nod], interv[2*nod+1]);
}



void read()
{
    f>>n>>m;
    for(int i = 1; i <= n; ++i)
        f>>valori[i];
    for(int i = 1; i < n; ++i)
    {
        f>>a>>b;
        graph[a].push_back(b);
        graph[b].push_back(a);
    }
    dfs(1, 0, 1);
    form_labels(1, 0, 1);
    for(int i = 1; i <= n; ++i)
        form_interv(1, 1, n, valori[i], idfs[i]);
    //afis(label_lant);
    //afis(tati);
    //afis(interv);

    for(int i = 1; i <= m; ++i)
    {
        f>>t>>a>>b;
        if(t == 0)
            update(1, 1, n, idfs[a], b);
        else g<<findmax(a, b)<<"\n";
    }

}





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