Cod sursa(job #1935444)

Utilizator FlorinHajaFlorin Gabriel Haja FlorinHaja Data 22 martie 2017 13:23:32
Problema Heavy Path Decomposition Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.79 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

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

const int nmax = 100005;
vector<int> ls[nmax], comp_lant[nmax];
int nlant;
int a[nmax], x, y, i, j, t, n, m;
int niv[nmax], greu[nmax];
bool viz[nmax];
int dimlant[nmax], carelant[nmax];
int tatalant[nmax], nivlant[nmax];
int arb[nmax], pozlant[nmax];

void dfs(int x) {
    int l = ls[x].size(), i, y, frunza = 1, k = -1;

    viz[x] = 1;
    greu[x] = 1;

    for (i = 0; i < l; i++) {
        y = ls[x][i];
        if (viz[y]) continue;

        frunza = 0;

        niv[y] = niv[x]+1;
        dfs(y);
        greu[x] += greu[y];

        if (k == -1) k = y;
        else if (greu[y] > greu[k]) k = y;
    }

    if (frunza) {
        nlant++;
        dimlant[nlant]=1;
        carelant[x] = nlant;
        comp_lant[nlant].push_back(x);
        return;
    }

    int k1 = k;
    k = carelant[k];
    dimlant[k]++;
    carelant[x] = k;
    comp_lant[k].push_back(x);

    for (i = 0; i < l; i++) {
        y = ls[x][i];
        if (niv[y] < niv[x] || y == k1) continue;
        k = carelant[y];
        tatalant[ k ] = x;
        nivlant[ k ] = niv[x];
    }

}

void build(int cod, int st, int dr, int decalaj, int lant) {

     if (st == dr) {
        arb[cod+decalaj] = a[ comp_lant[lant][st-1] ];
        return;
     }
     int mij = (st+dr)/2;
     build(2*cod, st, mij, decalaj, lant);
     build(2*cod+1, mij+1, dr, decalaj, lant);
     arb[cod+decalaj] = max(arb[2*cod + decalaj], arb[2*cod+1 + decalaj]);
}

int gx, val;

void update(int cod, int st, int dr, int decalaj) {
     if (st == dr) {
        arb[cod+decalaj] = val;
        return;
     }
     int mij = (st+dr)/2;

     if (gx <= mij)
        update(2*cod, st, mij, decalaj);
     else update(2*cod+1, mij+1, dr, decalaj);
     arb[cod+decalaj] = max(arb[2*cod + decalaj], arb[2*cod+1 + decalaj]);
}

int gl, gr;

int query(int cod, int st, int dr, int decalaj) {

     if (gl <= st && dr <= gr)
        return arb[cod+decalaj];

     int mij = (st+dr)/2, max1 = 0;
     if (gl <= mij)
        max1 = query(2*cod, st, mij, decalaj);
     if (mij < gr)
        max1 = max(max1, query(2*cod+1, mij+1, dr, decalaj));
     return max1;
}

void make_graph() {
    niv[1]=1;
    dfs(1);
    for (i = 1; i <= nlant; i++) {
        reverse(comp_lant[i].begin(), comp_lant[i].end());
        if (i > 1)
            pozlant[i] = pozlant[i-1] + 4 * dimlant[i-1];
        build(1, 1, dimlant[i], pozlant[i], i);
    }
}

void rezolva(int t, int x, int y) {
    if (t == 0) {
        int X = carelant[x];
        gx = niv[x] - nivlant[X];
        val = y;
        update(1, 1, dimlant[X], pozlant[X]);
        return;
    }

    int sol = 0;
    while (1) {

        if (carelant[x] == carelant[y]) {
            if (niv[x] > niv[y])
                swap(x, y);
            int X = carelant[x], Y = carelant[y];
            gl = niv[x] - nivlant[X];
            gr = niv[y] - nivlant[X];
            sol = max(sol, query(1, 1, dimlant[X], pozlant[X]) );
            break;
        }

        if (nivlant[carelant[x]] < nivlant[carelant[y]])
            swap(x, y);

        int X = carelant[x], Y = carelant[y];
        gl = 1;
        gr = niv[x] - nivlant[X];
        sol = max(sol, query(1, 1, dimlant[X], pozlant[X]) );
        x = tatalant[X];
    }
    g << sol << '\n';
}

int main() {
    f >> n >> m;
    for (i = 1; i <= n; i++)
        f >> a[i];
    for (i = 1; i < n; i++) {
        f >> x >> y;
        ls[x].push_back(y);
        ls[y].push_back(x);
    }
    make_graph();

    for (i = 1; i <= m; i++) {
        f >> t >> x >> y;
        rezolva(t,x,y);
    }

    return 0;
}