Cod sursa(job #2409808)

Utilizator alex2kamebossPuscasu Alexandru alex2kameboss Data 19 aprilie 2019 13:50:19
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.21 kb
#include <iostream>
#include <cstdio>
#include <vector>

#define N 100

using namespace std;

int n,m,x,y,k,c;
int val[N],d[N],t[N], lant[N], pozitie[N];
vector <int> g[N];
vector <int> lanturi[N];

struct Arbint{
    int *arbint;
    int len;

    Arbint(){
        len = 0;
    }

    Arbint(int l){
        len = lanturi[l].size()-1;
        arbint = new int[4*len];
        construieste(1,len,1,l);
    }

    void construieste(int st, int dr, int pos, int l){
        if(st==dr){
            arbint[pos] = val[lanturi[l][st]];
            return ;
        }

        int mij = (st+dr)/2;

        construieste(st,mij,2*pos,l);
        construieste(mij+1,dr,2*pos+1,l);

        arbint[pos] = max(arbint[2*pos],arbint[2*pos+1]);
    }

    void actualizare(int loc, int v){
        actualizare(loc,v,1,len,1);
    }

    void actualizare(int loc, int v, int st, int dr, int pos){
        if(st==dr){
            arbint[pos] = v;
            return;
        }

        int mij = (st+dr)/2;

        if(loc<=mij)
            actualizare(loc,v,st,mij,2*pos);
        else
            actualizare(loc,v,mij+1,dr,2*pos+1);

        arbint[pos] = max(arbint[2*pos],arbint[2*pos+1]);
    }

    int cautare(int qst, int qdr){
        return cautare(qst,qdr,1,len,1);
    }

    int cautare(int qst, int qdr, int st, int dr, int pos){
        if(qst<=st && dr<=qdr)
            return arbint[pos];

        int mij = (st+dr)/2;

        if(qdr<=mij)
            return cautare(qst,qdr,st,mij,2*pos);
        if(mij<qst)
            return cautare(qst,qdr,mij+1,dr,2*pos+1);
        return max(cautare(qst,qdr,st,mij,2*pos),
                cautare(qst,qdr,mij+1,dr,2*pos+1));
    }

}arbore[N];

int dfs(int nod, int niv){
    d[nod] = niv;
    int w = 1, fmax = 0, next;
    for(int i : g[nod])
        if(!d[i]){
            t[i] = nod;
            int loc = dfs(i,niv+1);
            w+=loc;
            if(loc>fmax){
                fmax = loc;
                next = lant[i];
            }
        }
    if(w==1){
        lanturi[k].push_back(-1);
        lanturi[k].push_back(nod);
        lant[nod] = k++;
        pozitie[nod]=1;
    }else{
        pozitie[nod] = lanturi[next].size();
        lanturi[next].push_back(nod);
        lant[nod] = next;
    }
    return w;
}

int cauta(int st, int dr){
    if(lant[st]==lant[dr])
        return arbore[lant[st]].cautare(min(pozitie[st],pozitie[dr]),
                    max(pozitie[st],pozitie[dr]));
    if(d[lanturi[lant[st]].back()]<d[lanturi[lant[dr]].back()])
        return max(cauta(st,t[lanturi[lant[dr]].back()]),
                arbore[lant[dr]].cautare(pozitie[dr],arbore[lant[dr]].len));
    return cauta(dr,st);
}

int main()
{
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);

    scanf("%d%d", &n,&m);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &val[i]);
    for(int i = 1; i < n; ++i){
        scanf("%d%d", &x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }

    dfs(1,1);
    for(int i = 0; i < k; ++i)
        arbore[i] = Arbint(i);

    for(int i = 0; i < m; ++i){
        scanf("%d%d%d", &c,&x,&y);
        if(c==0){
            arbore[lant[x]].actualizare(pozitie[x],y);
        }else{
            cout<<cauta(x,y)<<"\n";
        }
    }

    return 0;
}