Cod sursa(job #1552483)

Utilizator hrazvanHarsan Razvan hrazvan Data 18 decembrie 2015 09:34:29
Problema Heavy Path Decomposition Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 3.19 kb
#include <stdio.h>
#include <stdlib.h>
#define MAXN 100000
int val[MAXN], nrfii[MAXN], ad[MAXN];
int lant[MAXN], pos[MAXN], dl = 0;
int tlant[MAXN], nrl[MAXN];
int *arbl[MAXN];
int nod[2 * MAXN], next[2 * MAXN], ult[MAXN];

inline int max2(int a, int b){
  return a > b ? a : b;
}

void heavypath(int x, int tata){
  nrfii[x] = 1;
  int poz, max = 0, p = -1;
  poz = ult[x];
  while(poz != -1){
    if(nod[poz] != tata){
      ad[nod[poz]] = ad[x] + 1;
      heavypath(nod[poz], x);
      nrfii[x] += nrfii[nod[poz]];
      if(max < nrfii[nod[poz]]){
        max = nrfii[nod[poz]];
        p = nod[poz];
      }
    }
    poz = next[poz];
  }
  if(p == -1){
    lant[x] = dl;
    pos[x] = 0;
    dl++;
  }
  else{
    lant[x] = lant[p];
    pos[x] = pos[p] + 1;
  }
  tlant[lant[x]] = tata;
  nrl[lant[x]]++;
}

void upd(int *arb, int p, int st, int dr, int x, int y){
  if(st == dr){
    arb[p] = y;
  }
  else{
    int m = (st + dr) / 2;
    if(x <= m)
      upd(arb, 2 * p + 1, st, m, x, y);
    else
      upd(arb, 2 * p + 2, m + 1, dr, x, y);
    arb[p] = max2(arb[2 * p + 1], arb[2 * p + 2]);
  }
}

int query(int *arb, int p, int st, int dr, int x, int y){
  if(st >= x && dr <= y){
    return arb[p];
  }
  else{
    int a = 0, b = 0, m = (st + dr) / 2;
    if(x <= m)
      a = query(arb, 2 * p + 1, st, m, x, y);
    if(m + 1 <= y)
      b = query(arb, 2 * p + 2, m + 1, dr, x, y);
    return max2(a, b);
  }
}

inline int answer(int x, int y){
  int max = 0, aux, a, b;
  while(lant[x] != lant[y]){
    if(tlant[lant[x]] == -1)
      a = -1;
    else
      a = ad[tlant[lant[x]]];
    if(tlant[lant[y]] == -1)
      b = -1;
    else
      b = ad[tlant[lant[y]]];
    if(a < b){
      max = max2(max, query(arbl[lant[y]], 0, 0, nrl[lant[y]] - 1, pos[y], nrl[lant[y]] - 1));
      y = tlant[lant[y]];
    }
    else{
      max = max2(max, query(arbl[lant[x]], 0, 0, nrl[lant[x]] - 1, pos[x], nrl[lant[x]] - 1));
      x = tlant[lant[x]];
    }
  }
  if(pos[x] > pos[y]){
    aux = x;
    x = y;
    y = aux;
  }
  max = max2(max, query(arbl[lant[x]], 0, 0, nrl[lant[x]] - 1, pos[x], pos[y]));
  return max;
}

int main(){
  FILE *in = fopen("heavypath.in", "r");
  int n, m, i, j, x, y, t, dr = 0;
  fscanf(in, "%d%d", &n, &m);
  for(i = 0; i < n; i++){
    fscanf(in, "%d", &val[i]);
    ult[i] = -1;
  }
  for(i = 0; i < n - 1; i++){
    fscanf(in, "%d%d", &x, &y);
    x--;  y--;
    nod[dr] = x;
    next[dr] = ult[y];
    ult[y] = dr;
    dr++;
    nod[dr] = y;
    next[dr] = ult[x];
    ult[x] = dr;
    dr++;
  }
  ad[0] = 0;
  heavypath(0, -1);
  for(i = 0; i < dl; i++){
    arbl[i] = (int*)malloc(4 * 4 * nrl[i]);
    for(j = 0; j < 4 * nrl[i]; j++)
        arbl[i][j] = 0;
  }
  for(i = 0; i < n; i++)
    upd(arbl[lant[i]], 0, 0, nrl[lant[i]] - 1, pos[i], val[i]);
  FILE *out = fopen("heavypath.out", "w");
  for(i = 0; i < m; i++){
    fscanf(in, "%d%d%d", &t, &x, &y);
    if(t == 0){
      x--;
      upd(arbl[lant[x]], 0, 0, nrl[lant[x]] - 1, pos[x], y);
    }
    else{
      x--;
      y--;
      fprintf(out, "%d\n", answer(x, y));
    }
  }
  fclose(in);
  fclose(out);

  return 0;
}