Cod sursa(job #2355244)

Utilizator Daria09Florea Daria Daria09 Data 25 februarie 2019 22:04:22
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.9 kb
#include <bits/stdc++.h>
#define dim 100005
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int n,test,number,poz,Right,Left;
int daddy[dim],length[dim],bignode[dim],pos[dim],path[dim];
long long arb[dim*4+1],val[dim],ans,sol,Val;
vector <int> graph[dim];
void Update();
void Read()
{
    f>>n>>test;
    for(int i=1; i<=n; ++i)
        f>>val[i];
    for(int i=1; i<n; ++i)
    {
        int x,y;
        f>>x>>y;
        graph[x].push_back(y);
        graph[y].push_back(x);
    }
}
void Dfs(int node,int sugardaddy)
{
    daddy[node]=sugardaddy;
    length[node]=1;
    for(int i=0; i<graph[node].size(); ++i)
    {
        int son=graph[node][i];
        if(son!=sugardaddy)
        {
            Dfs(son,node);
            length[node]+=length[son];
            if(length[son]>length[bignode[node]])
                bignode[node]=son;
        }
    }
}
void HeavyDfs(int node,int sugardaddy)
{
    pos[node]=++number;
    path[node]=sugardaddy;
    if(length[node]>1)
    {
        HeavyDfs(bignode[node],sugardaddy);
        for(int i=0; i<graph[node].size(); ++i)
        {
            int son=graph[node][i];
            if(son!=bignode[node]&&son!=daddy[node])
                HeavyDfs(son,son);
        }
    }
}
void Update(int node,int st,int dr)
{
    if(st==dr)
        arb[node]=Val;
    else
    {
        int mij=(st+dr)/2;
        if(mij>=poz)Update(2*node,st,mij);
        else Update(2*node+1,mij+1,dr);
        if(arb[2*node]>arb[2*node+1])
            arb[node]=arb[2*node];
        else
            arb[node]=arb[2*node+1];
    }
}
void Query(int node,int st,int dr)
{
    if(Left<=st&&dr<=Right)
    {
        if(arb[node]>ans)
            ans=arb[node];
    }
    else
    {
        int mij=(st+dr)/2;
        if(Left<=mij)Query(2*node,st,mij);
        if(mij+1<=Right)Query(2*node+1,mij+1,dr);
    }
}
long long Answer(int x,int y)
{
    sol=0;
    while(path[x]!=path[y])
    {
        ans=0;
        if(pos[x]<pos[y])
        {
            Left=pos[path[y]];
            Right=pos[y];
            y=daddy[path[y]];
        }
        else
        {
            Left=pos[path[x]];
            Right=pos[x];
            x=daddy[path[x]];
        }
        Query(1,1,n);
        sol=max(ans,sol);
    }
    Left=min(pos[x],pos[y]);
    Right=max(pos[y],pos[x]);
    ans=0;
    Query(1,1,n);
    sol=max(ans,sol);
    return sol;
}
void Solve()
{
    int type,x,y;
    Dfs(1,0);
    HeavyDfs(1,1);
    for(int i=1; i<=n; ++i)
    {
        poz=pos[i];
        Val=val[i];
        Update(1,1,n);
    }
    for(int i=1; i<=test; ++i)
    {
        f>>type>>x>>y;
        if(type==0)
        {
            poz=pos[x];
            Val=y;
            Update(1,1,n);
        }
        else
            g<<Answer(x,y)<<'\n';
    }
}
int main()
{
    Read();
    Solve();
    return 0;
}