Cod sursa(job #2396935)

Utilizator greelioGreenio Greely greelio Data 3 aprilie 2019 22:56:00
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include<bits/stdc++.h>
#define N 100030
#define L (nod<<1)
#define R (L|1)

using namespace std;

int n,m;
vector<int>V[N];
int sz[N], lant[N], p[N], cnt[N], ord[N], bgn[N], lvl[N];
int nrlant,k, h[4*N], a[N];
//p parinte lant, ord nr ordine in land, cnt elem in lant

void update(int st, int dr, int nod, int idx, int val) {
    if (st==dr) {
        h[nod]=val;
        return;
    }
    int mid=(st+dr)>>1;
    if (idx<=mid) update(st,mid,L,idx,val);
    else update(mid+1,dr,R,idx,val);

    h[nod]=max(h[L], h[R]);
}

int query(int st, int dr, int nod, int l, int r) {
    if (l<=st && dr<=r) return h[nod];
    int mid=(st+dr)>>1;
    int left=0, right=0;
    if (l<=mid) left=query(st, mid, L, l, r);
    if (r>mid) right=query(mid+1,dr,R, l, r);
    return max(left, right);
}

void DFS(int x, int pr) {
    sz[x]=1;
    for (auto it:V[x]) {
        if (it!=pr) DFS(it, x), sz[x]+=sz[it];
    }
}

void HLD(int x, int pr, int depth) {
    int bigC=-1, mx=-1;
    lant[x]=nrlant;
    ord[x]=++cnt[nrlant];
    for (auto it:V[x])
        if (it!=pr && sz[it]>mx) mx=sz[it], bigC=it;

    if (bigC!=-1) HLD(bigC,x,depth);
    for (auto it:V[x]) {
        if (it!=pr && it!=bigC)  {
            p[++nrlant]=x;
            lvl[nrlant]=depth+1;
            HLD(it, x, depth+1);
        }
    }
    if (ord[x]==cnt[lant[x]]) bgn[lant[x]]=k+1, k+=cnt[lant[x]];
    update(1,n,1,bgn[lant[x]]+ord[x]-1, a[x]);
}

int main() {
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    cin>>n>>m;
    for (int i=1; i<=n; ++i) cin>>a[i];
    for (int i=1; i<n; ++i) {
        int x,y; cin>>x>>y;
        V[x].push_back(y);
        V[y].push_back(x);
    }
    DFS(1,-1);
    HLD(1,-1,0);

    for (int i=1; i<=m; ++i) {
        int c,x,y; cin>>c>>x>>y;
        if (!c) update(1,n,1,bgn[lant[x]]+ord[x]-1,y);
        else {
            int mx=0;
            while (lant[x]!=lant[y]) {
                if (lvl[lant[x]]<lvl[lant[y]]) swap(x,y);
                mx=max(mx, query(1,n,1,  bgn[lant[x]],  bgn[lant[x]]+ord[x]-1));
                x=p[lant[x]];
            }
            if (ord[x]>ord[y]) swap(x,y);
            mx=max(mx, query(1,n,1, bgn[lant[x]]+ord[x]-1, bgn[lant[x]]+ord[y]-1));
            cout<<mx<<'\n';
        }
    }

    return 0;
}