Cod sursa(job #998108)

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

void dfs(int nod, int prec) {
     lev[nod]=lev[prec]+1; lista p;
     for (p=arb[nod]; p; p=p->next)
        if (p->nod!=prec) dfs(p->nod,nod);
     int urm=0,mmax=0;
     for (p=arb[nod]; p; p=p->next)
     if (p->nod!=prec) {
         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 (p=arb[nod]; p; p=p->next)
           if (p->nod!=prec&&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,0);
   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);
}