Cod sursa(job #3138101)

Utilizator Luca529Taschina Luca Luca529 Data 17 iunie 2023 13:40:12
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.82 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
vector<int> v[100001], x[100001];
int n, k, k1, kk=1, y[100001], niv[100001], g[100001], lung[100001];
int dp[17][100001], log2[100001], d[500001], apar1[100001], apar2[100001];
bool p[100001];

void DFS(int nod)
{d[++k1]=nod;
 p[nod]=1;
 apar1[nod]=apar2[nod]=k1;

 vector<int>:: iterator I;
 for(I=v[nod].begin();I<v[nod].end();I++)
 if(p[*I]==0)
 {niv[*I]=niv[nod]+1;
  DFS(*I);

  g[nod]+=g[*I];
  d[++k1]=nod;
  apar2[nod]=k1;
 }
 g[nod]++;
}

void QS(int ind, int st, int dr)
{if(st<dr)
 {int i=st, j=dr, d=0;
  swap(v[ind][st], v[ind][(st+dr)/2]);

  while(i<j)
  {if(g[v[ind][i]]<g[v[ind][j]])swap(v[ind][i], v[ind][j]);
   i+=d;
   j-=1-d;
  }
  QS(ind, st, i-1);
  QS(ind, i+1, dr);
 }
}

struct nod{
int l, nr, t;
}nod[100001];

void DFS1(int no)
{int k=0;
 p[no]=0;
 vector<int>:: iterator I;
 for(I=v[no].begin();I<v[no].end();I++)
 if(p[*I]==1)
 {k++;
  if(k==1)nod[*I]={nod[no].l+1, nod[no].nr, nod[no].t}, lung[nod[no].nr]++;
  else nod[*I]={1, ++kk, no}, lung[kk]=1;
  DFS1(*I);
 }
}

void Update(int no, int st, int dr, int ind, int p, int v)
{if(st==dr)
 x[ind][no]=v;
 else
 {int mij=(st+dr)/2;

  if(mij>=p)Update(no*2, st, mij, ind, p, v);
  else Update(no*2+1, mij+1, dr, ind, p, v);

  x[ind][no]=max(x[ind][no*2], x[ind][no*2+1]);
 }
}

int Query(int no, int st, int dr, int ind, int qs, int qd)
{if(qs<=st && qd>=dr)
 return x[ind][no];
 else
 {int mij=(st+dr)/2;

  if(mij>=qd)return Query(no*2, st, mij, ind, qs, qd);
  if(mij<qs)return Query(no*2+1, mij+1, dr, ind, qs, qd);

  int a=Query(no*2, st, mij, ind, qs, qd), b=Query(no*2+1, mij+1, dr, ind, qs, qd);
  return max(a, b);
 }
}

void F(int r, int a, int b)
{int a1=0, b1=0;
 if(nod[r].nr==nod[a].nr)
 a1=Query(1, 1, lung[nod[a].nr], nod[a].nr, nod[r].l, nod[a].l);
 else
 {a1=Query(1, 1, lung[nod[a].nr], nod[a].nr, 1, nod[a].l);

  a=nod[a].t;
  while(nod[a].nr!=nod[r].nr)
  a=nod[a].t, a1=max(a1, Query(1, 1, lung[nod[a].nr], nod[a].nr, 1, nod[a].l));
  a1=max(a1, Query(1, 1, lung[nod[a].nr], nod[a].nr, nod[r].l, nod[a].l));
 }

 if(nod[r].nr==nod[b].nr)
 b1=Query(1, 1, lung[nod[b].nr], nod[b].nr, nod[r].l, nod[b].l);
 else
 {b1=Query(1, 1, lung[nod[b].nr], nod[b].nr, 1, nod[b].l);

  b=nod[b].t;
  while(nod[b].nr!=nod[r].nr)
  b=nod[b].t, b1=max(b1, Query(1, 1, lung[nod[b].nr], nod[b].nr, 1, nod[b].l));
  b1=max(b1, Query(1, 1, lung[nod[b].nr], nod[b].nr, nod[r].l, nod[b].l));
 }

 fout<<max(a1, b1)<<"\n";
}

int main()
{   int q, a, b, c;
    fin>>n>>q;
    for(int i=1;i<=n;i++)
    fin>>y[i];

    for(int i=1;i<n;i++)
    {fin>>a>>b;
     v[a].push_back(b);
     v[b].push_back(a);
    }

    niv[1]=1;
    DFS(1);
    for(int i=1;i<=n;i++)
    if(v[i].size()!=0)QS(i, 0, v[i].size()-1);

    nod[1]={1, 1}, lung[1]=1;
    nod[1].t=1;
    DFS1(1);

    for(int i=1;i<=k1;i++)
    {if(i!=1)log2[i]=log2[i/2]+1;
     dp[0][i]=d[i];
    }
    for(int i=1;i<=log2[k1];i++)
    for(int j=1<<i;j<=k1;j++)
    if(niv[dp[i-1][j-(1<<(i-1))]]<=niv[dp[i-1][j]])dp[i][j]=dp[i-1][j-(1<<(i-1))];
    else dp[i][j]=dp[i-1][j];

    for(int i=1;i<=kk;i++)
    for(int j=0;j<=4*lung[i];j++)
    x[i].push_back(0);

    for(int i=1;i<=n;i++)
    Update(1, 1, lung[nod[i].nr], nod[i].nr, nod[i].l, y[i]);

    for(int i=1;i<=q;i++)
    {fin>>a>>b>>c;

     if(a==0)
     {Update(1, 1, lung[nod[b].nr], nod[b].nr, nod[b].l, c);

      y[b]=c;
     }
     else
     {int r, v1=min(apar1[b], apar1[c]), v2=max(apar2[b], apar2[c]), dist;
      dist=log2[v2-v1+1];
      if(niv[dp[dist][v1+(1<<dist)]]<=niv[dp[dist][v2]])r=dp[dist][v1+(1<<dist)];
      else r=dp[dist][v2];

      F(r, b, c);
     }
    }
    return 0;
}