Cod sursa(job #2709207)

Utilizator valentinchipuc123Valentin Chipuc valentinchipuc123 Data 19 februarie 2021 23:36:17
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.19 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("heavypath.in");
ofstream g("heavypath.out");

int n,m,cost[100005],nr=0,aint[400005],niv[100005],sol;
int ctarb[100005],ltata[100005],lnivel[100005],lpoz[100005],nrdrumuri,diml[100005],loc[100005];

vector<int>G[100005],paths[100005];

void df(int nod,int tata,int height)
{
 ctarb[nod]=1;
 niv[nod]=height;
 int fiumax=-1;

 for(int i=0;i<G[nod].size();i++){
  int x=G[nod][i];

  if( x!=tata ){
    df(x,nod,height+1);

    ctarb[nod]+=ctarb[x];

    if(ctarb[nod]==-1) fiumax=x;
    else if(ctarb[fiumax]<ctarb[x]) fiumax=x;
  }
 }

 if( fiumax==-1 ){
  loc[nod]=++nrdrumuri;
  diml[nrdrumuri]=1;
  paths[nrdrumuri].push_back(nod);
  return;
 }

 loc[nod]=loc[fiumax];
 diml[loc[nod]]++;
 paths[loc[nod]].push_back(nod);

 for(int i=0;i<G[nod].size();i++){
   int x=G[nod][i];
   if( x!=fiumax&&x!=tata )
   {
    ltata[loc[x]]=nod;
    lnivel[loc[x]]=height;
   }
 }
}

void build(int nod,int st,int dr,int decalaj,int lant)
{
    if(st==dr){
      aint[nod+decalaj] = cost[paths[lant][st-1]];
      return;
    }
    int mid=(st+dr)/2;
    build(nod*2,st,mid,decalaj,lant);
    build(nod*2+1,mid+1,dr,decalaj,lant);

    aint[nod+decalaj] = max( aint[nod*2+decalaj],aint[nod*2+1+decalaj] );
}

void uptade(int nod,int st,int dr,int decalaj,int poz,int val)
{
    if( st==dr ){
      aint[nod+decalaj] = val;
      return;
    }
    int mid=(st+dr)/2;

    if(poz<=mid) uptade(nod*2,st,mid,decalaj,poz,val);
    else uptade(nod*2+1,mid+1,dr,decalaj,poz,val);

    aint[nod+decalaj] = max( aint[nod*2+decalaj],aint[nod*2+1+decalaj] );
}

void query(int nod,int st,int dr,int a,int b,int decalaj)
{
    if( a<=st&&dr<=b ){
      sol=max(sol,aint[nod+decalaj]);
      return;
    }
    int mid=(st+dr)/2;

    if(a<=mid) query(nod*2,st,mid,a,b,decalaj);
    if(mid<b) query(nod*2+1,mid+1,dr,a,b,decalaj);
}

void solve()
{

    for(int i=1;i<=m;i++)
    {
     int op1,op2,tip;
     f>>tip>>op1>>op2;
     if(tip==0){
         cost[op1]=op2;
         uptade(1,1,diml[loc[op1]],lpoz[loc[op1]],niv[op1]-lnivel[loc[op1]],op2);
     }
     else
     {
         sol=0;

         while(1)
         {
            if( loc[op1]==loc[op2] )
            {
             if( niv[op1]>niv[op2] )
                 swap(op1,op2);

             query(1,1,diml[loc[op1]],niv[op1]-lnivel[loc[op1]],niv[op2]-lnivel[loc[op2]],lpoz[loc[op1]]);
             break;
            }

            if( lnivel[loc[op1]]<lnivel[loc[op2]] )
                swap(op1,op2);

            query(1,1,diml[loc[op1]],1,niv[op1]-lnivel[loc[op1]],lpoz[loc[op1]]);

            op1=ltata[loc[op1]];
         }
         g<<sol<<'\n';
     }
    }
}

int main()
{
    f>>n>>m;
    for(int i=1; i<=n; i++)
        f>>cost[i];

    for(int i=1; i<n; i++)
    {
        int x,y;
        f>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
    }

    df(1,0,1);

    ///creez drumurile

    for(int i=1;i<=nrdrumuri;i++){

     reverse(paths[i].begin(),paths[i].end());

     if(i>1) lpoz[i]=lpoz[i-1]+4*diml[i-1];

     build(1,1,diml[i],lpoz[i],i);
    }
    ///
    solve();
}