Cod sursa(job #1535188)

Utilizator timicsIoana Tamas timics Data 24 noiembrie 2015 13:55:57
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.69 kb
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<bitset>
#define pb push_back
using namespace std;

int N,M,q,x,y,K;
int poz[1000100],v[100100],nr[100100],l[100100],p[100100],cmp[100100],viz[100100];
vector<int> g[100100], c[100100];

//Aint stuff
vector<vector<int> > t; 
void update(int comp, int nod, int st, int dr, int c, int d) {
    if(st==dr) { t[comp][nod]=d; return; }
    int mij = (st+dr)/2;
    if(c<=mij) update(comp,2*nod,st,mij,c,d);
    else update(comp,2*nod+1,mij+1,dr,c,d);
    t[comp][nod] = max(t[comp][2*nod],t[comp][2*nod+1]);
}
int getmax(int comp, int nod, int st, int dr, int c, int d) {
    int ret = 0; 
    if(c<=st && dr<=d) return t[comp][nod];
    int mij = (st+dr)/2;
    if(d>mij) ret = max(ret,getmax(comp,nod*2+1,1+mij,dr,c,d));
    if(c<=mij) ret = max(ret,getmax(comp,nod*2,st,mij,c,d));
    return ret;
}
inline int query_val(int comp, int st, int dr) {
    return getmax(comp, 1, 1, c[comp].size(), st+1, dr+1); 
}
 
//Available queries
inline void update_val(int comp, int poz, int val) {
    update(comp, 1, 1, c[comp].size(), poz+1, val);
    v[c[comp][poz]] = val;
}
int find_max(int x, int y) {
    if(cmp[x] == cmp[y]) return query_val(cmp[x],min(poz[x],poz[y]),max(poz[x],poz[y]));
    int px = p[c[cmp[x]][0]], py = p[c[cmp[y]][0]];
    if(l[px] < l[py]) { swap(x,y); swap(px,py); }
    int M = query_val(cmp[x],0,poz[x]);
    return max(M, find_max(px,y));
}
 
void dfs(int x) {
    viz[x] = 1; nr[x] = 1;
    int ind = -1, nrc = -1;
    for(auto y: g[x]) {
        if(viz[y]) continue;
        l[y] = l[x] + 1; p[y] = x; dfs(y);
        if(nr[y] > nrc) { ind = y; nrc = nr[y]; }
        nr[x] += nr[y];
    }
    if(nrc == -1) {
        vector<int> C; C.pb(x); 
        ++K; c[K] = C; cmp[x] = K;
    } else {
        c[cmp[ind]].pb(x); cmp[x] = cmp[ind];
    }
}

void heavy_path(int r) {
    K = 0;
    l[r] = 1;
    dfs(r);
    for(int i=1;i<=K;++i) {
        reverse(c[i].begin(),c[i].end());
        for(int j=0;j<c[i].size();++j) {
            poz[c[i][j]] = j;
        }
    }
    t.resize(K+10);
    for(int i=1;i<=K;++i) {
        t[i].resize(4*c[i].size()+10,0);
    }
    for(int i=1;i<=N;++i) {
        update_val(cmp[i],poz[i],v[i]);
    }
}
 
int main() {
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdin);
    scanf("%d%d",&N,&M);
    for(int i=1;i<=N;++i) {
        scanf("%d",&v[i]);
    }
    for(int i=1;i<N;++i) {
        scanf("%d%d",&x,&y);
        g[x].pb(y);
        g[y].pb(x);
    }
    heavy_path(1);

    for(int i=1;i<=M;++i) {
        scanf("%d%d%d",&q,&x,&y);
        if(q==0) {
            update_val(cmp[x],poz[x],y);
        } else {
            printf("%d\n",find_max(x,y));
        }
    }
    return 0;
}