Блог пользователя draid

Автор draid, история, 4 месяца назад, По-английски

i was tackling C. Experience the other day and had a "clever" idea (well it's perhaps the intended but whatever) to support all the queries mentioned in the problem in $$$O(\alpha(n))$$$, using both union by size/rank and path compression, i thought it was nice and didn't see it documented elsewhere so here it is, the idea is to basically notice that if we merge two teams (with union by size/rank ofc), we can set the experience of the child representative node to that of it self minus of it's parent representative experience, so basically:

now if we want the experience of B, we can traverse the tree up and sum, so $$$x-y+y = x$$$ and if we at some point added some value m to A, we'll have B equal x + A, and when path compression we'll just add experience of the recursion, let's describe what each dsu part will do:

sunion(a, b): regular union by size, but we set experience of the children representative to itself minus of it's parent

void sunion(int a, int b) {
  a = find(a);
  b = find(b);
  if(a == b) return;
  if(size[a] > size[b]) {
    parents[b] = a;
    size[a] += size[b];
    exp[b] -= exp[a];
  }
  
  else {
    parents[a] = b;
    size[b] += size[a];
    exp[a] -= exp[a];
  }
}

find(v): regular path compression, we go up the tree and move the link, but we add a twist that for each move up we sum the experience, code: (**incorrect code but the idea is there, can anyone help me figure out what's wrong? i spent two days on this :sob:**)

pair<int, int> find_backend(int v) {
  if(v == parents[v]) return {v, exp[v]};
  else {
    parents[v] = find_backend(parents[v]).first;
    exp[v] += find_backend(parents[v]).second;
    return {parents[v], exp[v]};
  }
}

int find(int v) {
  return find_backend(v).first;
}

get_exp(v): and add_exp(v, m) both trivial

int get_exp(int v) {
  return find_backend(v).second;
}

void add_exp(int v, int m) {
  exp[find(v)] += m; 
}

and yes that's it, we solved the problem in $$$O(\alpha(n))$$$! very cleanly, very nicely! i'd really appreciate some debugging help to make the code correct, sorry for my lack of implementation skills!

  • Проголосовать: нравится
  • +6
  • Проголосовать: не нравится