Cod sursa(job #2369402)

Utilizator DimaTCDima Trubca DimaTC Data 5 martie 2019 22:59:48
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include<bits/stdc++.h>
#define N 100005
#define L (nod<<1)
#define R L|1

using namespace std;

vector<int>V[N];
int a[N], mxc[N], dif[N],k;
int lant,idx[N], lvl[N],cnt[N], ord[N];
int h[263000], p[N];
int n,q; //idx lant //cnt-nr 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);
}

int DFS(int x, int pr) {
    int s=0,mxs=0,p=0;
    for (auto it:V[x]) {
        if (it!=pr) {
            int y=DFS(it,x);
            s+=y;
            if (y>mxs) p=it,mxs=y;
        }
    }
    mxc[x]=p;
    return s+1;
}

void DFS2(int x, int pr, int c, int h) {//c-idx lant
    idx[x]=c; cnt[c]++; ++k;
    if (idx[pr]==c) ord[x]=ord[pr]+1;
    else ord[x]=1;

    if (mxc[x]) DFS2(mxc[x],x,c,h);
    for (auto it:V[x]) {
        if (it!=pr && it!=mxc[x]) {
            p[++lant]=x; lvl[lant]=h+1;
            DFS2(it,x, lant,h+1);
        }
    }
    if (V[x].size()==1 && (x!=1||n==1)) dif[c]=k-cnt[c]+1;
    update(1,n,1, dif[c]+ord[x]-1, a[x]);
}

int main() {
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    cin>>n>>q;
    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);
    DFS2(1,-1,++lant,0);
    while (q--) {
        int c,x,y; cin>>c>>x>>y;
        if (!c) {
            update(1,n,1,dif[idx[x]]+ord[x]-1, y);
        } else {
            int rs=0;
            while (!(lvl[idx[x]]==lvl[idx[y]] && idx[x]==idx[y])) {
                if (lvl[idx[x]]<lvl[idx[y]]) swap(x,y);
                rs=max(rs, query(1,n,1,dif[idx[x]], dif[idx[x]]+ord[x]-1));
                x=p[idx[x]];
            }
            if (ord[x]>ord[y]) swap(x,y);
            rs=max(rs,query(1,n,1,dif[idx[x]]+ord[x]-1, dif[idx[x]]+ord[y]-1));
            cout<<rs<<'\n';
        }
    }

    return 0;
}