Cod sursa(job #3173460)

Utilizator raileanu-alin-gabrielRaileanu Alin-Gabriel raileanu-alin-gabriel Data 22 noiembrie 2023 21:49:27
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <iostream>
const int LOG=17;
const int NMAX=100005;

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

vector <int> v[NMAX], path;
int val[NMAX], poz[NMAX], sz[NMAX], pth[NMAX];
int niv[NMAX], w[NMAX], hv[NMAX];
int t[NMAX], aint[4*NMAX];
int n, q, nrp, cnt;

void build(int, int, int);
void update(int, int, int, int, int);
int query(int, int, int, int, int);
void dfs2(int, int);
void decomp();
void ord();
int query_hpd(int, int);
void update_hpd(int, int);
bool cmp(int a, int b)
{
  if(niv[a]==niv[b]) return a<b;
  return niv[a]<niv[b];
}

int main()
{
  int i, tip, a, b;
  fin>>n>>q;
  for(i=1; i<=n; i++) fin>>w[i];
  for(i=1; i<n; i++)
  {
    fin>>a>>b;
    v[a].push_back(b);
    v[b].push_back(a);
  }
  t[1]=1;
  dfs2(1, 1);
  decomp();
  ord();
  for(i=1; i<=q; i++)
  {
    fin>>tip>>a>>b;
    if(tip==0) update_hpd(a, b);
    else fout<<query_hpd(a, b)<<'\n';
  }
  return 0;
}

void update_hpd(int nod, int val)
{
  update(1, 1, n, poz[nod], val);
}

int query_hpd(int a, int b)
{
  int maxim=0;
  while(true)
  {
    if(pth[a]==pth[b])
    {
      maxim=max(maxim, query(1, 1, n, poz[a], poz[b]));
      break;
    }
    if(niv[a]>niv[b]) swap(a, b);
    maxim=max(maxim, query(1, 1, n, poz[path[pth[b]]], poz[b]));
    b=t[path[pth[b]]];
  }
  return maxim;
}

void ord()
{
  int i, nr=0;
  for(i=1; i<=n; i++) val[poz[i]]=w[i];
  build(1, 1, n);
}

void decomp()
{
  int nod, i, cnt=0;
  path.push_back(0);
  for(i=1; i<=n; i++) val[i]=i;
  sort(val+1, val+n+1, cmp);
  for(i=1; i<=n; i++)
  {
    if(!pth[val[i]])
    {
      ++nrp;
      nod=val[i];
      path.push_back(nod);
      while(true)
      {
        //l-am adaugat in path-ul nrp
        pth[nod]=nrp;
        poz[nod]=++cnt;
        if(hv[nod]==0) break;
        nod=hv[nod];
      }
    }
  }
}

void dfs2(int nod, int lvl)
{
  sz[nod]=1;
  niv[nod]=lvl;
  for(auto i:v[nod])
  {
    if(!sz[i])
    {
      t[i]=nod;
      dfs2(i, lvl+1);
      sz[nod]+=sz[i];
      if(sz[hv[nod]]<sz[i]) hv[nod]=i;
    }
  }
  v[nod].clear();
}

void build(int nod, int st, int dr)
{
  if(st==dr)
  {
    aint[nod]=val[st];
    return;
  }
  int mij=(st+dr)/2;
  build(2*nod, st, mij);
  build(2*nod+1, mij+1, dr);
  aint[nod]=max(aint[2*nod], aint[2*nod+1]);
}

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

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