Cod sursa(job #2409688)

Utilizator alexandra_udristoiuUdristoiu Alexandra Maria alexandra_udristoiu Data 19 aprilie 2019 12:43:23
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.36 kb
#include<fstream>
#include<vector>
#define DIM 100005
using namespace std;
int n, q, i, ii, jj, x, y, nr, tip, maxim;
int t[DIM], niv[DIM], poz[DIM], tl[DIM], lt[DIM], aint[4 * DIM], viz[DIM], val[DIM], ad[DIM], num[DIM];
vector<int> v[DIM], w[DIM];
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
void dfs(int nod){
    int i, vecin, ii = 0;
    viz[nod] = num[nod] = 1;
    for(i = 0; i < v[nod].size(); i++){
        int vecin = v[nod][i];
        if(viz[vecin] == 0){
            niv[vecin] = niv[nod] + 1;
            t[vecin] = nod;
            dfs(vecin);
            if(num[ii] < num[vecin]){
                ii = vecin;
            }
            num[nod] += num[vecin];
        }
    }
    if(ii == 0){
        nr++;
        lt[nod] = nr;
        w[nr].push_back(nod);
    }
    else{
        lt[nod] = lt[ii];
        w[ lt[nod] ].push_back(nod);
    }
}
void build(int p, int nod, int st, int dr, int ad){
    if(st == dr){
        aint[nod + ad] = val[ w[p][st - 1] ];
    }
    else{
        int mid = (st + dr) / 2;
        build(p, 2 * nod, st, mid, ad);
        build(p, 2 * nod + 1, mid + 1, dr, ad);
        aint[nod + ad] = max(aint[2 * nod + ad], aint[2 * nod + 1 + ad]);
    }
}
void update(int nod, int st, int dr, int ad, int p, int x){
    if(st == dr){
        aint[nod + ad] = x;
    }
    else{
        int mid = (st + dr) / 2;
        if(p <= mid){
            update(2 * nod, st, mid, ad, p, x);
        }
        else{
            update(2 * nod + 1, mid + 1, dr, ad, p, x);
        }
        aint[nod + ad] = max(aint[2 * nod + ad], aint[2 * nod + 1 + ad]);
    }
}
void query(int nod, int st, int dr, int ad, int p, int u){
    if(p <= st && dr <= u){
        maxim = max(maxim, aint[nod + ad]);
    }
    else{
        int mid = (st + dr) / 2;
        if(p <= mid){
            query(2 * nod, st, mid, ad, p, u);
        }
        if(u > mid){
            query(2 * nod + 1, mid + 1, dr, ad, p, u);
        }
    }
}
int main(){
    fin>> n >> q;
    for(i = 1; i <= n; i++){
        fin>> val[i];
    }
    for(i = 1; i < n; i++){
        fin>> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1);
    for(i = 1; i <= nr; i++){
        for(ii = 0, jj = w[i].size() - 1; ii < jj; ii++, jj--){
            swap(w[i][ii], w[i][jj]);
        }
        tl[i] = t[ w[i][0] ];
        for(ii = 0; ii < w[i].size(); ii++){
            poz[ w[i][ii] ] = ii;
        }
        ad[i] = ad[i - 1] + 4 * w[i - 1].size();
        build(i, 1, 1, w[i].size(), ad[i]);
    }
    niv[0] = -1;
    for(; q; q--){
        fin>> tip >> x >> y;
        if(tip == 0){
            update(1, 1, w[ lt[x] ].size(), ad[ lt[x] ], poz[x] + 1, y);
            continue;
        }
        maxim = 0;
        while(lt[x] != lt[y]){
            ii = tl[ lt[x] ];
            jj = tl[ lt[y] ];
            if(niv[ii] > niv[jj]){
                query(1, 1, w[ lt[x] ].size(), ad[ lt[x] ], 1, poz[x] + 1);
                x = ii;
            }
            else{
                query(1, 1, w[ lt[y] ].size(), ad[ lt[y] ], 1, poz[y] + 1);
                y = jj;
            }
        }
        if(poz[x] > poz[y]){
            swap(x, y);
        }
        query(1, 1, w[ lt[x] ].size(), ad[ lt[x] ], poz[x] + 1, poz[y] + 1);
        fout<< maxim <<"\n";
    }
    return 0;
}