Cod sursa(job #2091509)

Utilizator tqmiSzasz Tamas tqmi Data 19 decembrie 2017 19:23:31
Problema Heavy Path Decomposition Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.34 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define Nmax 100000
using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

int V[Nmax+5];
int use[Nmax+5],niv[Nmax+5],L[Nmax+5],LD[Nmax+5],LP[Nmax+5],w[Nmax+5],LT[Nmax+5],LN[Nmax+5],AI[4*Nmax +5],NL,N,M;

vector <int> G[Nmax+5];
vector <int> P[Nmax+5];

void dfs(int nod){
    use[nod]=1;
    int frunza = 1, nh = -1;
    for(int i=0;i<G[nod].size();i++){
        int vecin = G[nod][i];
        if(use[vecin]) continue;
        frunza = 0;
        niv[vecin] = niv[nod]+1;
        dfs(vecin);
        w[nod]+=w[vecin];
        if(nh==-1)
            nh = vecin;
        else if(w[nh] < w[vecin])
            nh = vecin;
    }

    if(frunza){
        L[nod] = ++NL;
        LD[NL] = 1;
        P[NL].push_back(nod);
        return;
    }

    L[nod] = L[nh];
    ++LD[L[nod]];
    P[L[nod]].push_back(nod);

    for(int i=0;i<G[nod].size();i++){
        int vecin = G[nod][i];
        if(vecin!=nh && niv[vecin]>=niv[nod]){
            LT[L[vecin]] = nod;
            LN[L[vecin]] = niv[nod];
        }
    }
}

void build(int nod,int st,int dr,int dec,int lant){
    if(st==dr){
        AI[nod + dec] = V[P[lant][st-1]];
        return;
    }
    int mid = (st+dr)/2;
    build(nod*2,st,mid,dec,lant);
    build(nod*2+1,mid+1,dr,dec,lant);
    AI[nod + dec] = max(AI[nod*2 + dec],AI[nod*2+1 + dec]);
}

void conf(){
    niv[1]=1;
    dfs(1);
    for(int i=1;i<=NL;i++)
    {
        reverse(P[i].begin(),P[i].end());
        if(i>1)
            LP[i] = LP[i-1] + LD[i-1] *4;
        build(1,1,LD[i],LP[i],i);
    }
}

void update(int nod, int st, int dr, int poz, int val, int dec){
    if(st == dr)
    {
        AI[nod + dec] = val;
        return;
    }
    int mid = (st+dr)/2;
    if(poz<=mid)
        update(nod*2,st,mid,poz,val,dec);
    else
        update(nod*2+1,mid+1,dr,poz,val,dec);
    AI[nod + dec] = max(AI[nod*2 + dec],AI[nod*2+1 + dec]);
}

int query(int nod,int st,int dr,int qst,int qdr,int dec){
    if(qst<=st && dr<=qdr){
        return AI[nod + dec];
    }
    int mid = (st+dr)/2;
    int sol = 0;
    if(qst<=mid)
        sol = max(sol,query(nod*2,st,mid,qst,qdr,dec));
    if(qdr>mid)
        sol = max(sol,query(nod*2+1,mid+1,dr,qst,qdr,dec));
    return sol;

}

void read(){
    fin>>N>>M;
    for(int i=1;i<=N;i++)
    {
        fin>>V[i];
    }
    for(int i=1;i<N;i++){
        int x,y;
        fin>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    conf();
    for(int l=1;l<=M;l++){
        int t,x,y;
        fin>>t>>x>>y;
        if(!t)
            update(1,1,LD[L[x]],niv[x] - LN[L[x]],y,LP[L[x]]);
        else
        {
            int sol = 0;
            while(1){
                if(L[x] == L[y]){
                    if(niv[x]>niv[y])
                        swap(x,y);
                    sol = max(sol,query(1,1,LD[L[x]],niv[x] - LN[L[x]],niv[y] - LN[L[x]],LP[L[x]]));
                    break;
                }
                if(LN[L[x]]<LN[L[y]])
                    swap(x,y);
                sol = max(sol,query(1,1,LD[L[x]],1,niv[x] - LN[L[x]],LP[L[x]]));
                x = LT[L[x]];
            }
            fout<<sol<<"\n";
        }
    }
}



int main()
{
    read();
    return 0;
}