Cod sursa(job #1807911)

Utilizator alexandra_udristoiuUdristoiu Alexandra Maria alexandra_udristoiu Data 17 noiembrie 2016 08:07:08
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.84 kb
#include<fstream>
#include<vector>
#define DIM 100005
using namespace std;
int n, m, nr, i, j, x, y, sol, ii, jj, ti, maxim;
int aint[5 * DIM], val[DIM], t[DIM], viz[DIM], ad[DIM], ln[DIM], ind[DIM], num[DIM], tl[DIM], niv[DIM];
vector<int> v[DIM], lant[DIM];
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
void dfs(int nod, int tata){
    viz[nod] = 1;
    int ii = 0;
    t[nod] = tata;
    niv[nod] = niv[tata] + 1;
    num[nod] = 1;
    for(int i = 0; i < v[nod].size(); i++){
        int vecin = v[nod][i];
        if(viz[vecin] == 0){
            dfs(vecin, nod);
            num[nod] += num[vecin];
            if(num[ vecin ] > num[ii]){
                ii = vecin;
            }
        }
    }
    if(ii == 0){
        nr++;
        ln[nod] = nr;
        lant[nr].push_back(nod);
        tl[nr] = t[nod];
    }
    else{
        ii = ln[ii];
        ln[nod] = ii;
        tl[ii] = t[nod];
        lant[ii].push_back(nod);
    }
}
void build(int nod, int st, int dr, int t){
    if(st == dr){
        aint[nod + ad[t] ] = val[ lant[t][st - 1] ];
    }
    else{
        int mid = (st + dr) / 2;
        build(2 * nod, st, mid, t);
        build(2 * nod + 1, mid + 1, dr, t);
        aint[nod + ad[t] ] = max(aint[2 * nod + ad[t] ], aint[2 * nod + 1 + ad[t] ]);
    }
}
void update(int nod, int st, int dr, int poz, int val, int add){
    if(st == dr){
        aint[nod + add] = val;
    }
    else{
        int mid = (st + dr) / 2;
        if(poz <= mid){
            update(2 * nod, st, mid, poz, val, add);
        }
        else{
            update(2 * nod + 1, mid + 1, dr, poz, val, add);
        }
        aint[nod + add] = max(aint[2 * nod + add], aint[2 * nod + 1 + add]);
    }
}
void query(int nod, int st, int dr, int p, int u, int add){
    if(p <= st && dr <= u){
        maxim = max(maxim, aint[nod + add]);
    }
    else{
        int mid = (st + dr) / 2;
        if(p <= mid){
            query(2 * nod, st, mid, p, u, add);
        }
        if(u > mid){
            query(2 * nod + 1, mid + 1, dr, p, u, add);
        }
    }
}
int main(){
    fin>> n >> m;
    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);
    }
    //niv[1] = 1;
    dfs(1, 0);
    for(i = 1; i <= nr; i++){
        for(ii = 0, jj = lant[i].size() - 1; ii < jj; ii++, jj--){
            swap(lant[i][ii], lant[i][jj]);
            ind[ lant[i][ii] ] = ii;
            ind[ lant[i][jj] ] = jj;
        }
        if(ii == jj){
            ind[ lant[i][ii] ] = ii;
        }
        ad[i] = ad[i - 1] + 4 * lant[i - 1].size();
    }
    for(i = 1; i <= nr; i++){
        build(1, 1, lant[i].size(), i);
    }
    for(; m; m--){
        fin>> ti >> x >> y;
        if(ti == 1){
            sol = 0;
            while(ln[x] != ln[y]){
                ii = ln[x];
                jj = ln[y];
                maxim = 0;
                if(niv[ tl[ii] ] > niv[ tl[jj] ]){
                    query(1, 1, lant[ii].size(), 1, ind[x] + 1, ad[ii]);
                    sol = max(sol, maxim);
                    x = tl[ii];
                }
                else{
                    query(1, 1, lant[jj].size(), 1, ind[y] + 1, ad[jj]);
                    sol = max(sol, maxim);
                    y = tl[jj];
                }
            }
            maxim = 0;
            ii = ind[x];
            jj = ind[y];
            x = ln[x];
            if(jj < ii){
                swap(ii, jj);
            }
            query(1, 1, lant[x].size(), ii + 1, jj + 1, ad[x]);
            sol = max(sol, maxim);
            fout<< sol <<"\n";
        }
        else{
            ii = ln[x];
            update(1, 1, lant[ii].size(), ind[x] + 1, y, ad[ii]);
        }
    }
    return 0;
}