Cod sursa(job #1963827)

Utilizator razvandRazvan Dumitru razvand Data 12 aprilie 2017 20:15:47
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.29 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <climits>

using namespace std;

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

int V[100003];
vector<int> v[100003];
int subt[100003];
int lant[100003];
bool viz[100003];
vector<int> la[100003];
int poz[100003];
int parent[100003];
int parentN[100003];
int niv[100003];
int tim;

void dfs(int nod) {
    if(subt[nod] != 0)
        return;
    subt[nod] = 1;
    for(int i = 0; i < v[nod].size(); i++) {
        if(subt[v[nod][i]] == 0) {
            parentN[v[nod][i]] = nod;
            niv[v[nod][i]] = niv[nod]+1;
            dfs(v[nod][i]);
            subt[nod] += subt[v[nod][i]];
        }
    }
}

void lan(int nod) {
    if(viz[nod])
        return;
    viz[nod] = 1;
    pair<int, int> bst;
    for(int i = 0; i < v[nod].size(); i++) {
        if(viz[v[nod][i]])
            continue;
        lan(v[nod][i]);
        if(subt[v[nod][i]] > bst.first)
            bst = {subt[v[nod][i]], v[nod][i]};
    }
    if(bst.second == 0)
        lant[nod] = ++tim;
    else
        lant[nod] = lant[bst.second];
    la[lant[nod]].push_back(nod);
    poz[nod] = la[lant[nod]].size();
    for(int i = 0; i < v[nod].size(); i++)
        if(lant[v[nod][i]] != lant[nod])
            parent[lant[v[nod][i]]] = v[nod][i];
}

void upd(int N, int p, int vf, int l, int r, vector<int> &A) {
    if(l == r) {
        A[N] = vf;
        return;
    }
    int mid = (l+r)/2;
    if(p <= mid)
        upd(2*N, p, vf, l, mid, A);
    else
        upd(2*N+1, p, vf, mid+1, r, A);
    A[N] = max(A[2*N], A[2*N+1]);
}

int que(int N, int lt, int rt, int l, int r, vector<int> &A) {

    if(l >= lt && r <= rt)
        return A[N];

    int mid = (l+r)/2;
    int mx = -1;

    if(lt <= mid)
        mx = max(mx, que(2*N, lt, rt, l, mid, A));
    if(rt >= mid+1)
        mx = max(mx, que(2*N+1, lt, rt, mid+1, r, A));

    return mx;

}

int ans(int x, int y) {
    if(lant[x] == lant[y])
        return que(1, min(poz[x], poz[y]), max(poz[x], poz[y]), 1, la[lant[x]].size()/4, la[lant[x]]);
    if(niv[parent[lant[x]]] < niv[parent[lant[y]]])
        swap(x, y);
    int mx = que(1, poz[x], la[lant[x]].size(), 1, la[lant[x]].size()/4, la[lant[x]]);
    //int mx = 8;
    return max(mx, ans(parentN[parent[lant[x]]], y));
}

int main() {

    int n,m;
    in >> n >> m;

    for(int i = 1; i <= n; i++)
        in >> V[i];

    int x,y;

    for(int i = 1; i <= n-1; i++) {
        in >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }

    niv[1] = 1;
    dfs(1);
    lan(1);
    int sz = 0;
    vector<int> temp;

    for(int i = 1; i <= n; i++) {
        temp = la[i];
        la[i].clear();
        la[i].resize(temp.size()*4);
        for(int j = 0; j < temp.size(); j++) {
            //cout << la[i].size() << " " << temp[j] << '\n';
            upd(1, j+1, V[temp[j]], 1, la[i].size()/4, la[i]);
        }
    }

    for(int i = 1; i <= n; i++)
        viz[i] = false;

    int z;

    for(int i = 1; i <= m; i++) {

        in >> x >> y >> z;

        if(x == 0) {
            upd(1, poz[y], z, 1, la[lant[y]].size()/4, la[lant[y]]);
        } else {
            out << ans(y, z) << '\n';
        }

    }

    return 0;
}