Cod sursa(job #998105)

Utilizator ctlin04UAIC.VlasCatalin ctlin04 Data 15 septembrie 2013 18:59:49
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.02 kb
#include<fstream>
#include<algorithm>
using namespace std;
typedef struct celula {
          int nod;
          celula *next;
          }*lista;
lista arb[100005],aux[100005],v;
int i,n,m,value[100005],whpath[100005],whpos[100005],x,y,nrfiisb[100005],tata[100005],nrpath,op,lev[100005];
int parent[100005],nrn[100005],sol;
int *laint[100005];

void dfs(int nod) {
     lev[nod]=lev[tata[nod]]+1;
     for (lista p=arb[nod]; p; p=p->next)
      if (p->nod!=tata[nod]){ tata[p->nod]=nod; dfs(p->nod); }
     int urm,mmax=0;
     for (lista p=arb[nod]; p; p=p->next)
     if (p->nod!=tata[nod]) {
         nrfiisb[nod]+=nrfiisb[p->nod];
         if (nrfiisb[p->nod]>mmax) { mmax=nrfiisb[p->nod]; urm=p->nod; }
         }
     nrfiisb[nod]+=1;
     if (nrfiisb[nod]==1) {
                          ++nrpath; whpath[nod]=nrpath; nrn[nrpath]=1;
                          v=new celula; v->nod=nod; v->next=aux[nrpath]; aux[nrpath]=v;
                          }
     else {
          v=new celula; v->nod=nod; v->next=aux[whpath[urm]]; aux[whpath[urm]]=v;
          whpath[nod]=whpath[urm]; ++nrn[whpath[nod]];
          for (lista p=arb[nod]; p; p=p->next)
           if (p->nod!=tata[nod]&&p->nod!=urm) parent[whpath[p->nod]]=nod;
           }
}

void update(int lant, int poz, int valoare, int nod, int l, int r){
     if (l==r) laint[lant][nod]=valoare;
     else {
          int mid=(l+r)/2;
          if (poz<=mid) update(lant,poz,valoare,2*nod,l,mid);
                 else update(lant,poz,valoare,2*nod+1,mid+1,r);
          laint[lant][nod]=max(laint[lant][2*nod],laint[lant][2*nod+1]);
          }
}

void querry(int lant, int x, int y, int nod, int l, int r) {
     if (l>=x&&r<=y) sol=max(sol,laint[lant][nod]);
      else {
           int mid=(l+r)/2;
           if (x<=mid) querry(lant,x,y,2*nod,l,mid);
           if (y>mid) querry(lant,x,y,2*nod+1,mid+1,r);
           }
}

void rezolva(int x, int y) {
     if (whpath[x]==whpath[y]) querry(whpath[x],min(whpos[y],whpos[x]),max(whpos[y],whpos[x]),1,1,nrn[whpath[x]]);
      else {
           if (lev[parent[whpath[y]]]>lev[parent[whpath[x]]]) swap(x,y);
           querry(whpath[x],1,whpos[x],1,1,nrn[whpath[x]]);
           rezolva(parent[whpath[x]],y);
           }
}

int main(void) {
   ifstream fin("heavypath.in");
   ofstream fout("heavypath.out");
   fin>>n>>m;
   for (i=1; i<=n; ++i) fin>>value[i];
   for (i=1; i<n; ++i) {
       fin>>x>>y;
       v=new celula; v->nod=x; v->next=arb[y]; arb[y]=v;
       v=new celula; v->nod=y; v->next=arb[x]; arb[x]=v;
       }
   dfs(1);
   for (i=1; i<=nrpath; ++i) {
        laint[i]=new int[4*nrn[i]]; 
          int pas=0; 
        for (lista p=aux[i]; p; p=p->next) { ++pas; whpos[p->nod]=pas; update(i,pas,value[p->nod],1,1,nrn[i]); }
       }
   for (i=1; i<=m; ++i){
       fin>>op>>x>>y;
       if (op==0) update(whpath[x],whpos[x],y,1,1,nrn[whpath[x]]);
         else {
              sol=0;
              rezolva(x,y);
              fout<<sol<<"\n";
              }
     }
  return(0);
}