Cod sursa(job #1705231)

Utilizator DjokValeriu Motroi Djok Data 20 mai 2016 09:16:06
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.5 kb
#include<bits/stdc++.h>
using namespace std;

typedef struct lnod {
    int nod;
    lnod *next;
}*nod;

int i,n,q,a[100005],x,y,op,*arb[50005],rs,poz[100005];
int lvl[100005],tata[100005],NrFii[100005],path[100005],Npath[50005],nr;
nod lda[100005],aux[50005];

void add(int x,nod &y) {
    nod p=new lnod;
    p->nod=x;
    p->next=y;
    y=p;
}

void dfs(int x,int t) {
    int cnt=0,sub=0;

    lvl[x]=lvl[t]+1; ++NrFii[x];

    for(nod p=lda[x];p;p=p->next)
    if(p->nod!=t) dfs(p->nod,x);

    for(nod p=lda[x];p;p=p->next)
    if(p->nod!=t)
    {
      NrFii[x]+=NrFii[p->nod];
      if(NrFii[p->nod]>cnt) cnt=NrFii[p->nod],sub=p->nod;
    }

    if(NrFii[x]==1) path[x]=++nr,Npath[nr]=1,add(x,aux[nr]);
    else {
           add(x,aux[path[sub]]);
           ++Npath[path[sub]];
           path[x]=path[sub];

           for(nod p=lda[x];p;p=p->next)
           if(p->nod!=t && p->nod!=sub) tata[path[p->nod]]=x;
         }
}

void update(int lant,int left,int right,int nod) {
    if(left==right) arb[lant][nod]=y;
    else {
           int pivot=(left+right)/2;
           if(x<=pivot) update(lant,left,pivot,2*nod);
           else update(lant,pivot+1,right,2*nod+1);
           arb[lant][nod]=max(arb[lant][2*nod],arb[lant][2*nod+1]);
         }
}

void query(int lant,int left,int right,int nod) {
    if(x<=left && y>=right) rs=max(rs,arb[lant][nod]);
    else {
           int pivot=(left+right)/2;
           if(x<=pivot) query(lant,left,pivot,2*nod);
           if(y>pivot) query(lant,pivot+1,right,2*nod+1);
         }
}

void Solve(int A,int B) {
    if(path[A]==path[B]) x=min(poz[A],poz[B]),y=max(poz[A],poz[B]),query(path[A],1,Npath[path[A]],1);
    else {
           if(lvl[tata[path[A]]]<lvl[tata[path[B]]]) swap(A,B);

           x=1; y=poz[A]; query(path[A],1,Npath[path[A]],1);

           Solve(tata[path[A]],B);
         }
}

int main()
{
  ifstream cin("heavypath.in");
  ofstream cout("heavypath.out");

  ios_base::sync_with_stdio(0); cin.tie(0);

  cin>>n>>q;
  for(i=1;i<=n;++i) cin>>a[i];

  for(i=1;i<n;++i)
  {
    cin>>x>>y;
    add(x,lda[y]);
    add(y,lda[x]);
  }

  dfs(1,1);

  for(i=1,x=0;i<=nr;++i,x=0)
  {
    arb[i]=new int[4*Npath[i]+5];

    for(nod p=aux[i];p;p=p->next) poz[p->nod]=++x,y=a[p->nod],update(i,1,Npath[i],1);
  }

  while(q--)
  {
    cin>>op>>x>>y;

    if(!op) op=x,x=poz[x],update(path[op],1,Npath[path[op]],1);
    else rs=-1e9+69,Solve(x,y),cout<<rs<<'\n';
  }

 return 0;
}