Cod sursa(job #1650710)

Utilizator Liviu98Dinca Liviu Liviu98 Data 11 martie 2016 20:00:07
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.91 kb
#include <iostream>
#include <stdio.h>
#include <vector>
#define NMax 100005
#define ArbMax 400005
using namespace std;
vector<int> Graf[NMax],Chain[NMax];
int N,M,value[NMax],lant[NMax],level[NMax],weight[NMax];
int tata[NMax],position[NMax],aibase[NMax];
int Arb[ArbMax],vpos;
bool mark[NMax];
int n1;

void DFS(int nod)
{
    int MaxW=0;
    mark[nod]=true,weight[nod]=1;
    for(vector<int>::iterator it=Graf[nod].begin();it!=Graf[nod].end();it++)
    {
        if(mark[*it]==true)
            continue;
        tata[*it]=nod;
        level[*it]=level[nod]+1;
        DFS(*it);
        if(weight[*it]>weight[MaxW])
            MaxW=*it;
        weight[nod]=weight[nod]+weight[*it];
    }
    if(MaxW)
        lant[nod]=lant[MaxW];
    else
        lant[nod]=++n1;
    Chain[lant[nod]].push_back(nod);
}

void BuildArbore(int nod,int s,int d)
{
    if(s==d)
    {
        Arb[nod]=value[aibase[s]];
        return;
    }
    int mij=(s+d)/2;
    BuildArbore(nod*2,s,mij);
    BuildArbore(nod*2+1,mij+1,d);
    Arb[nod]=max(Arb[nod*2],Arb[2*nod+1]);
}

void UpdateArbore(int x,int val,int nod,int s,int d)
{
    if(s==d)
    {
        Arb[nod]=val;
        return;
    }
    int mij=(s+d)/2;
    if(x>mij)
        UpdateArbore(x,val,nod*2+1,mij+1,d);
    else
        UpdateArbore(x,val,nod*2,s,mij);
    Arb[nod]=max(Arb[2*nod],Arb[2*nod+1]);
}

inline int AflaTata(int x)
{
    return tata[Chain[x].back()];
}

int AflaRang(int x,int y,int nod,int s,int d)
{
    if(d<x || s>y)
        return 0;
    if(s>=x && d<=y)
        return Arb[nod];
    return max(AflaRang(x,y,nod*2,s,(s+d)/2),AflaRang(x,y,nod*2+1,(s+d)/2+1,d));
}

int Query(int x,int y)
{
    int vmx=0;
    while(lant[x]!=lant[y])
    {
        int ttx=AflaTata(lant[x]),tty=AflaTata(lant[y]);
        if(level[ttx]>level[tty])
        {
            vmx=max(vmx,AflaRang(position[x],position[Chain[lant[x]].back()],1,1,N));
            x=ttx;
        }
        else
        {
            vmx=max(vmx,AflaRang(position[y],position[Chain[lant[y]].back()],1,1,N));
            y=tty;
        }
    }
    if(position[x]>position[y])
        swap(x,y);
    return max(vmx,AflaRang(position[x],position[y],1,1,N));
}
int main()
{
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);
    int i,x,y;
    scanf("%d%d",&N,&M);
    for(i=1;i<=N;++i)
        scanf("%d",&value[i]);
    for(i=1;i<=N-1;++i)
    {
        scanf("%d%d",&x,&y);
        Graf[x].push_back(y);
        Graf[y].push_back(x);
    }
    level[1]=1;
    DFS(1);
    for(i=1;i<=n1;++i)
        for(size_t j=0;j<Chain[i].size();++j)
            aibase[position[Chain[i][j]]=++vpos]=Chain[i][j];
    BuildArbore(1,1,N);
    while(M--)
    {
        scanf("%d%d%d",&i,&x,&y);
        if(i)
            printf("%d\n",Query(x,y));
        else
            UpdateArbore(position[x],y,1,1,N);
    }
}