Cod sursa(job #1698286)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 4 mai 2016 01:07:49
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 kb
#include <fstream>
#include <vector>

using namespace std;

const int N_MAX = 100005;

int n, m, chains;
vector<int> graph[N_MAX], chain[N_MAX];
int v[N_MAX], siz[N_MAX], h[N_MAX], indx[N_MAX], upLink[N_MAX], pos[N_MAX], node[N_MAX], t[2 * N_MAX];

void Dfs(int x, int p) {
   int best = 0;

   h[x] = 1 + h[p];
   siz[x] = 1;

   for(auto y : graph[x]) {
      if(y != p) {
         Dfs(y, x);
         siz[x] += siz[y];
         if(siz[best] < siz[y]) best = y;
      }
   }

   for(auto y : graph[x]) {
      if(y != p && y != best) {
         upLink[indx[y]] = x;
      }
   }

   indx[x] = (!best ? ++chains : indx[best]);
   chain[indx[x]].push_back(x);
}

void Build() {
   for(int i = n; i; i--)
      t[i] = max(t[i << 1], t[i << 1 | 1]);
}

void Update(int p, int v) {
   for(t[p += n] = v; p > 1; p >>= 1)
      t[p >> 1] = max(t[p], t[p ^ 1]);
}

int Query(int l, int r) {
   int ret = 0;

   for(l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if(l & 1)
         ret = max(ret, t[l++]);
      if(r & 1)
         ret = max(ret, t[--r]);
   }

   return ret;
}

int HeavyQuery(int x, int y) {
   int ret = 0;

   while(indx[x] != indx[y]) {
      if(h[upLink[indx[x]]] < h[upLink[indx[y]]]) swap(x, y);
      ret = max(ret, Query(pos[x], pos[chain[indx[x]].back()] + 1));
      x = upLink[indx[x]];
   }

   if(pos[x] > pos[y]) swap(x, y);
   return max(ret, Query(pos[x], pos[y] + 1));
}

void PrepareChains() {
   Dfs(1, 0);
   for(int i = 1, j = 0; i <= chains; i++) {
      for(auto x : chain[i]) {
         pos[x] = ++j;
         node[j] = x;
         t[j + n] = v[x];
      }
   }
   Build();
}

int main() {
   ifstream f("heavypath.in");
   ofstream g("heavypath.out");

   int i, qt, x, y;

   f >> n >> m;

   for(i = 1; i <= n; i++)
      f >> v[i];

   for(i = 1; i < n; i++) {
      f >> x >> y;
      graph[x].push_back(y);
      graph[y].push_back(x);
   }

   PrepareChains();

   while(m--) {
      f >> qt >> x >> y;
      if(qt == 0)
         Update(pos[x], y);
      else
         g << HeavyQuery(x, y) << '\n';
   }

   return 0;
}