Cod sursa(job #2440167)

Utilizator smoc_georgemarianSmoc George-Marian smoc_georgemarian Data 17 iulie 2019 19:37:46
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.94 kb
#include <bits/stdc++.h>
#define NMAX 100100
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

int n,m,nrc ;

int v[NMAX];
int lvl[NMAX];
bool uz[NMAX];
int nrf[NMAX];
int whatc[NMAX];
int positioninchain[NMAX];
int fatherch[NMAX];

vector <int>g[NMAX];
vector <int>chain[NMAX];
vector<int> a[NMAX];
int x,y,op,i,j;

void citire();
void build(int ch, int node, int st, int dr);
void df(int k, int lvl, int fath);
int querya_int(int ch, int node, int st, int dr, int x, int y);
int query_r(int x, int y);
void update(int ch, int node, int st, int dr, int poz, int val);
int main()
{citire();
 df(1,0,0);


 //fout<<chain[whatc[9]].size();
     for (i=1;i<=nrc;i++)
        for (int j=0;j<2*chain[i].size();j++)
            a[i].push_back(0);
 for(i=1;i<=nrc;i++)
      build(i,1,0,chain[i].size()-1);

  //fout<<query_r(6,8);
   //fout<<v[9];
  for(i=1;i<=m;i++)
    {
     fin>>op>>x>>y;
     if(op==0)
         update(whatc[x],1,0,chain[whatc[x]].size()-1,positioninchain[x],y);
         else
         {
          fout<<query_r(x,y)<<'\n';
         }
    }
    return 0;
}
void citire()
{int i,x,y;
  fin>>n>>m;
  for(i=1;i<=n;i++)
    fin>>v[i];
for(i=1;i<n;i++)
    {
     fin>>x>>y;
     g[x].push_back(y);
     g[y].push_back(x);
    }
}
void df(int k,int niv, int tata)
{int i;
 bool ok=0;
 ///prima data
  uz[k]=1; nrf[k]=1;lvl[k]=niv;
 ///
 for(i=0;i<g[k].size();i++)
    if(!uz[g[k][i]])
        {
        ok=1;
        df(g[k][i],niv+1,k);
        nrf[k]+=nrf[g[k][i]];
        }
 if(!ok) ///frunza
    {
     chain[++nrc].push_back(k);
     //fout<<nrc<<" "<<chain[nrc][0]<<'\n';
     whatc[k]=nrc;
     positioninchain[k]=0;
    }
    else
    {
     int maxim=0;int care=-1;
      for(i=0;i<g[k].size();i++)
        if( nrf[g[k][i]]>maxim && g[k][i]!=tata)
            {maxim=nrf[g[k][i]];care=g[k][i];}
    // fout<<care<<" ";
    chain[whatc[care]].push_back(k);
    whatc[k]=whatc[care];
    positioninchain[k]=chain[whatc[care]].size()-1;
    ///la momentul asta tatal e chiar k pt toate celalt(e in exterior)
     for(i=0;i<g[k].size();i++)
          if(g[k][i]!=care && g[k][i]!=tata)
            {
             fatherch[whatc[g[k][i]]]=k;
            }
    }
}
void build(int ch, int node, int st, int dr)
{
 if(st==dr)
    {a[ch][node]=v[chain[ch][st] ];return;}
  int mj=(st+dr)/2;
  build(ch,2*node,st,mj);
  build(ch,2*node+1,mj+1,dr);
  a[ch][node]=max(a[ch][2*node],a[ch][2*node+1]);

}
int querya_int(int ch, int node, int st, int dr, int x, int y)
{int val1=0,val2=0;
 if(x<=st && dr<=y)
        return a[ch][node];
 int mj=(st+dr)/2;
 if(x<=mj)
    val1=querya_int(ch,2*node,st,mj,x,y);
  if(y>mj)
    val2=querya_int(ch,2*node+1,mj+1,dr,x,y);
  return max(val1,val2);

}
int query_r(int x, int y)
{int maxim=0;
 int tata;
 if(whatc[x]==whatc[y])
    {
     //x=positioninchain[x];
     //y=positioninchain[y];
     if(positioninchain[x]>positioninchain[y])
        swap(x,y);
     return querya_int(whatc[x],1,0,chain[whatc[x]].size()-1,positioninchain[x],positioninchain[y]);
    }
 if(lvl[fatherch[whatc[x]]] >  lvl[fatherch[whatc[y]]] )
    {int max2=0;
     max2= querya_int(whatc[x],1,0,chain[whatc[x]].size()-1,positioninchain[x],chain[whatc[x]].size()-1)  ;
     maxim= max(max2,maxim);
     tata=fatherch[whatc[x]];
     maxim=max(maxim,query_r(tata,y) );

    }
    else
    {
     maxim=max(maxim, querya_int(whatc[y],1,0,chain[whatc[y]].size()-1,positioninchain[y],chain[whatc[y]].size()-1)  );
     tata=fatherch[whatc[y]];
     maxim=max(maxim,query_r(tata,x) );
    }
  return maxim;
}
void update(int ch, int node, int st, int dr, int poz, int val)
{//fout<<node<<" ";
    if(st==dr)
        {a[ch][node]=val;return;}
   int mj=(st+dr)/2;
   if(poz<=mj)
    update(ch,2*node,st,mj,poz,val);
    else
    update(ch,2*node+1,mj+1,dr,poz,val);
   a[ch][node]=max(a[ch][2*node],a[ch][2*node+1]);
}