Cod sursa(job #2196217)

Utilizator cristibogdanPatrascu Cristian cristibogdan Data 18 aprilie 2018 19:35:54
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.35 kb
#include<fstream>
#include<vector>
#define NMAX 100005
using namespace std;
int n, m, i, x, y, ii, jj, sol, nr, q,k,j;
int  t[NMAX], tl[NMAX], ind[NMAX], aint[5 * NMAX], L[NMAX] ,niv[NMAX], num[NMAX], viz[NMAX], st[NMAX], val[NMAX];
vector<int> G[NMAX], A[NMAX];
ifstream f("heavypath.in");
ofstream g("heavypath.out");
void dfs(int nod){
    viz[nod] = num[nod] = 1;
    int ii = 0;
    for(int i = 0; i < G[nod].size(); i++){
        int next= G[nod][i];
        if(viz[next] == 0){
            t[next] = nod;
            niv[next] = niv[nod] + 1;
            dfs(next);
            num[nod] += num[next];
            if(num[next] > num[ii]){
                ii = next;
            }
        }
    }
    if(ii == 0){
        nr++;
        L[nod] = nr;
        A[nr].push_back(nod);
        tl[nr] = t[nod];
    }
    else{
        L[nod] = L[ii];
        A[ L[ii] ].push_back(nod);
        tl[ L[ii] ] = t[nod];
    }
}
void build(int nod, int st, int dr, int p, int i){
    if(st == dr){
        aint[nod + p] = val[ A[i][st - 1] ];
    }
    else{
        int mid = (st + dr) / 2;
        build(2 * nod, st, mid, p, i);
        build(2 * nod + 1, mid + 1, dr, p, i);
        aint[nod + p] = max(aint[2 * nod + p], aint[2 * nod + 1 + p]);
    }
}
void update(int nod, int st, int dr, int x, int y, int p){
    if(st == dr){
        aint[nod + p] = y;
    }
    else{
        int mid = (st + dr) / 2;
        if(x <= mid){
            update(2 * nod, st, mid, x, y, p);
        }
        else{
            update(2 * nod + 1, mid + 1, dr, x, y, p);
        }
        aint[nod + p] = max(aint[2 * nod + p], aint[2 * nod + 1 + p]);
    }
}
void query(int nod, int st, int dr, int x, int y, int p){
    if(x <= st && dr <= y){
        sol = max(sol, aint[nod + p]);
    }
    else{
        int mid = (st + dr) / 2;
        if(x <= mid){
            query(2 * nod, st, mid, x, y, p);
        }
        if(y > mid){
            query(2 * nod + 1, mid + 1, dr, x, y, p);
        }
    }
}
int main(){
    f >> n >> m;
    for(i = 1; i <= n; i++){
        f >> val[i];
    }
    for(i = 1; i < n; i++){
        f >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1);
    for(i = 1; i <= nr; i++){
        for(k = 0, j = A[i].size() - 1; k <= j; k++, j--){
            swap(A[i][k], A[i][j]);
            ind[ A[i][k] ] = k + 1;
            ind[ A[i][j] ] = j + 1;
        }
        st[i] = st[i - 1] + 4 * A[i - 1].size();
        build(1, 1, A[i].size(), st[i], i);
    }
    niv[0] = -1;
    for(; m; m--){
        f >> q >> x >> y;
        if(q == 0){
            val[x] = y;
            ii = L[x];
            update(1, 1, A[ii].size(), ind[x], y, st[ii]);
            continue;
        }
        sol = 0;
        while(L[x] != L[y]){
            ii = L[x];
            jj = L[y];
            if(niv[ tl[ii] ] > niv[ tl[jj] ]){
                query(1, 1, A[ii].size(), 1, ind[x], st[ii]);
                x = tl[ii];
            }
            else{
                query(1, 1, A[jj].size(), 1, ind[y], st[jj]);
                y = tl[jj];
            }
        }
        ii = L[x];
        x = ind[x];
        y = ind[y];
        if(x > y){
            swap(x, y);
        }
        query(1, 1, A[ii].size(), x, y, st[ii]);
        g<< sol <<"\n";
    }
    return 0;
}