Cod sursa(job #2343094)

Utilizator refugiatBoni Daniel Stefan refugiat Data 13 februarie 2019 18:06:07
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.75 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
ifstream si("heavypath.in");
ofstream so("heavypath.out");
const int MAXN=100005;
vector<int> v[MAXN], arb[MAXN];
int val[MAXN], s[MAXN], niv[MAXN], lant[MAXN], lp[MAXN], ls[MAXN], lt[MAXN], nlant;
void dfs(int nod, int tata, int lvl) {
    s[nod]=1;
    niv[nod]=lvl;
    vector<int>::iterator i;
    for(i=v[nod].begin(); i!=v[nod].end(); ++i)
        if(*i!=tata) {
            dfs(*i, nod, lvl+1);
            s[nod]+=s[*i];
        }
}
void dfs1(int nod, int tata, int l) {
    lant[nod]=l;
    ++ls[l];
    lp[nod]=ls[l];
    int h=0;
    vector<int>::iterator i;
    for(i=v[nod].begin(); i!=v[nod].end(); ++i) {
        if(*i!=tata&&s[*i]>s[h])
            h=*i;
    }
    if(!h)
        return;
    dfs1(h, nod, l);
    for(i=v[nod].begin(); i!=v[nod].end(); ++i) {
        if(*i!=tata&&*i!=h) {
            ++nlant;
            lt[nlant]=nod;
            dfs1(*i, nod, nlant);
        }
    }
}
void update(int nod, int st, int dr, int poz, int val, vector<int>&arb) {
    if(st==dr) {
        arb[nod]=val;
        return;
    }
    int mid=(st+dr)>>1;
    if(poz<=mid)
        update(nod*2, st, mid, poz, val, arb);
    else
        update(nod*2+1, mid+1, dr, poz, val, arb);
    arb[nod]=max(arb[nod*2], arb[nod*2+1]);
}
int query(int nod, int st, int dr, int qs, int qd, vector<int> &arb) {
    if(qs<=st&&qd>=dr)
        return arb[nod];
    int mid=(st+dr)/2, sol=0;
    if(qs<=mid) {
        sol=max(sol, query(nod*2, st, mid, qs, qd, arb));
    }
    if(qd>mid) {
        sol=max(sol, query(nod*2+1, mid+1, dr, qs, qd, arb));
    }
    return sol;
}
int main() {
    int n, m, x, y, q;
    si>>n>>m;
    for(int i=1; i<=n; i++)
        si>>val[i];
    for(int i=1; i<n; ++i) {
        si>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1, 0, 1);
    nlant=1;
    dfs1(1, 0, nlant);
    for(int i=1; i<=nlant; ++i)
        arb[i].resize(ls[i]*4);
    for(int i=1; i<=n; ++i)
    {
        update(1, 1, ls[lant[i]], lp[i], val[i], arb[lant[i]]);
    }
    for(int i=1; i<=m; ++i)
    {
        si>>q>>x>>y;
        if(q==0)
            update(1, 1, ls[lant[x]], lp[x], y, arb[lant[x]]);
        else
        {
            int sol=0;
            while(lant[x]!=lant[y])
            {
                if(niv[lt[lant[x]]]<niv[lt[lant[y]]])
                    swap(x, y);
                sol=max(sol, query(1, 1, ls[lant[x]], 1, lp[x], arb[lant[x]]));
                x=lt[lant[x]];
            }
            if(lp[x]>lp[y])
                swap(x, y);
            sol=max(sol, query(1, 1, ls[lant[x]], lp[x], lp[y], arb[lant[x]]));
            so<<sol<<'\n';
        }
    }
    return 0;
}