Cod sursa(job #2606194)

Utilizator isa_tudor_andreiAndrei Tudor isa_tudor_andrei Data 27 aprilie 2020 11:57:58
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.23 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int NMAX = 100000;

class AINT{
public:
  int *tree, nodes;
  AINT (int n) {
    nodes = n;
    tree = new int[4 * n];
  }
  void update( int node, int st, int dr, int poz, int val ) {
    if( st == dr ) {
      tree[node] = val;
      return ;
    }
    int mid = (st + dr) / 2;
    if( poz <= mid )
      update(2*node, st, mid, poz, val);
    else
      update(2*node + 1, mid + 1, dr, poz, val);

    tree[node] = max( tree[2*node], tree[2*node + 1] );
  }

  int query( int node, int st, int dr, int left, int right ) {
    if( dr < left || st > right )
      return 0;

    if( left <= st && dr <= right )
      return tree[node];
    int mid = (st + dr) / 2;
    return max( query(2*node, st, mid, left, right),
                query(2*node + 1, mid + 1, dr, left, right) );
  }

  void op0( int poz, int val ) {
    update(1, 1, nodes, poz, val);
  }

  int op1( int st, int dr ) {
    return query(1, 1, nodes, st, dr);
  }
};

vector<int> G[NMAX + 1];
vector<vector<int>> lanturi;
vector<AINT> path;
int tata[NMAX + 1], values[NMAX + 1], level[NMAX + 1], carelant[NMAX + 1], pos[NMAX + 1], k;

int dfs( int node, int father ) {
  int nrd = 1, maxim = 0, tolant;
  tata[node] = father;
  for( const auto &it : G[node] ) {
    if( it != father ) {
      level[it] = 1 + level[node];
      int val = dfs( it, node );
      nrd += val;
      if( val > maxim ) {
        maxim = val;
        tolant = carelant[it];
      }
    }
  }
  if( maxim == 0 ) {
    lanturi.push_back({0, node});
    carelant[node] = k ++;
  }
  else {
    carelant[node] = tolant;
    lanturi[tolant].push_back(node);
  }
  return nrd;
}

bool cmp( int a, int b ) {
  return level[a] < level[b];
}

int raspuns( int x, int y ) {
  int bucketx = carelant[x];
  int buckety = carelant[y];
  int parentx = lanturi[bucketx][1];
  int parenty = lanturi[buckety][1];
  if( level[parentx] < level[parenty] )
    swap(x, y), swap(parentx, parenty), swap(bucketx, buckety);
  int sz = lanturi[bucketx].size() - 1;

  if( parentx == parenty ) {
    int st = min(pos[x], pos[y]);
    int dr = max(pos[x], pos[y]);
    return path[bucketx].op1(st, dr);
  }
  int nextnode = tata[parentx];
  return max( path[bucketx].op1(1, pos[x]), raspuns(nextnode, y) );
}

int main() {
    int n, m;
    fin>>n>>m;
    for( int i = 1; i <= n; i ++ )
      fin>>values[i];
    for( int i = 1; i <= n - 1; i ++ ) {
      int u, v;
      fin>>u>>v;
      G[u].push_back(v);
      G[v].push_back(u);
    }
    dfs(1, 0);
    for( int i = 0; i < k; i ++ ) {
      sort(lanturi[i].begin() + 1, lanturi[i].end(), cmp);

      int sz = lanturi[i].size();
      path.push_back(AINT(sz - 1));

      for( int j = 1; j < sz; j ++ ) {
        int node = lanturi[i][j];
        pos[node] = j;
        path[i].op0(j, values[node]);
      }
    }

    for( int i = 1; i <= m; i ++ ) {
      int op, x, y;
      fin>>op>>x>>y;
      if( op == 0 ) {
        int bucket = carelant[x];
        path[bucket].op0(pos[x], y);
      }
      else {
        fout<<raspuns(x, y)<<"\n";
      }
    }
    return 0;
}