Cod sursa(job #1518744)

Utilizator DjokValeriu Motroi Djok Data 6 noiembrie 2015 12:03:30
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include<bits/stdc++.h>
using namespace std;

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

int i,n,m,x,y,op,a[100005],tata[50005],NrNod[50005],NrFii[100005],LVL[100005],path[100005],poz[100005],rs,NrPath,*arb[50005];
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 sub=0,Nr=0;

    LVL[x]=LVL[t]+1;

    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]>Nr) Nr=NrFii[p->nod],sub=p->nod;
    }

    ++NrFii[x];

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

           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,NrNod[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,NrNod[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>>m;
  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,0);

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

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

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

    if(op) rs=0,Solve(x,y),cout<<rs<<'\n';
    else op=x,x=poz[x],update(path[op],1,NrNod[path[op]],1);
  }

 return 0;
}