Cod sursa(job #1970274)

Utilizator FlorinHajaFlorin Gabriel Haja FlorinHaja Data 19 aprilie 2017 08:08:02
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.23 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

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

const int nmax = 100005;
int hv[nmax], care[nmax], ttr[nmax], tt[nmax], lg[nmax];
int niv[nmax], nivl[nmax], K, n, m, x, y, i, j, t;
bool viz[nmax], UPD;
int arb[4*nmax], ind, v[nmax], gx, gy, mm, smax, dcl[nmax];
vector<int> ls[nmax], comp[nmax];

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

    for (i = 0; i < l; i++) {
        y = ls[x][i];
        if (viz[y]==1)continue;
        frunza = 0;
        niv[y]=niv[x]+1;
        dfs(y);
        hv[x] += hv[y];
        if (hv[k] < hv[y] || k == -1) k = y;
    }
    if (frunza) {
        care[x] = ++K;
        lg[K]++;
        comp[K].push_back(x);
        return;
    }
    care[x] = care[k];
    lg[care[k]]++;
    comp[care[k]].push_back(x);

    for (i = 0; i < l; i++) {
        y = ls[x][i];
        if (y == k || niv[x] > niv[y]) continue;
        tt[care[y]] = x;
        nivl[care[y]] = niv[x];
    }
}

void baga(int decal, int cod, int st, int dr) {
    if (st == dr) {
        arb[decal+cod] = v[comp[ind][st-1]];
        return;
    }
    int mij = (st+dr)/2;
    if (UPD == 0) {
        baga(decal, 2*cod, st, mij);
        baga(decal, 2*cod+1, mij+1, dr);
    } else {
        if (gx <= mij) baga(decal, 2*cod, st, mij);
        else baga(decal, 2*cod+1, mij+1, dr);
    }
    arb[decal+cod] = max(arb[decal+2*cod], arb[decal+2*cod+1]);
}

void query(int decal, int cod, int st, int dr) {
    if (gy <= 0) return;
    if (gx <= st && dr <= gy) {
        mm = max(mm, arb[decal+cod]);
        return;
    }
    int mij = (st+dr)/2;
    if (gx <= mij) query(decal, 2*cod, st, mij);
    if (gy > mij) query(decal, 2*cod+1, mij+1, dr);
}


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

    niv[1] = 1;
    dfs(1);
    for (i = 1; i <= K; i++)
        reverse(comp[i].begin(), comp[i].end());
    for (i = 1; i <= K; i++) {
        dcl[i+1] = dcl[i]+4*lg[i];
        UPD = 0, ind = i;
        baga(dcl[i], 1, 1, lg[i]);
    }


    for (i = 1; i <= m; i++) {
        f >> t >> x >> y;
        if (t == 0) {
            ind = care[x];
            v[x] = y;
            gx = niv[x] - nivl[care[x]];
            UPD = 1;
            baga(dcl[ind], 1, 1, lg[ind]);
        } else {
            smax = 0;
            while (care[x] != care[y]) {
                if (nivl[care[x]] < nivl[care[y]]) swap(x,y);
                mm = 0;
                ind = care[x];
                gx = 1, gy = niv[x]-nivl[ind];


                query(dcl[ind], 1, 1, lg[ind]);

                x = tt[ind];
                smax = max(smax, mm);

            }
            if (niv[x] < niv[y]) swap(x,y);
            gx = niv[y]-nivl[care[y]];
            gy = niv[x]-nivl[care[x]];
            mm = 0;
            ind = care[x];
            query(dcl[care[x]], 1, 1, lg[care[x]]);
            smax = max(smax, mm);

            g << smax << '\n';
        }
    }
}