import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;
class Answer {
private static final int parent(int height, int node) {
int size
= (int)Math.
pow(2, height
) - 1;
if (node == size) {
return -1;
}
int before = 0;
do {
if (size == 0) {
}
size >>>= 1;
int left = before + size;
int right = left + size;
int me = right + 1;
if (left == node || right == node) {
return me;
}
if (node > left) {
before = left;
}
} while (true);
}
public static final int[] answerToo(int height, int[] nodes) {
return IntStream.of(nodes).map(n -> parent(height, n)).toArray();
}
public static final int[] answer(int height, int[] nodes) {
int[] ans = new int[nodes.length];
Map
<Integer, Integer
> indices
= new HashMap
<>(); IntStream.range(0, nodes.length).forEachOrdered(i -> indices.put(nodes[i], i));
int next = postOrder(height, 0, 0, indices, ans);
if (next < 0) {
int i = indices.get(-next);
ans[i] = -1;
}
return ans;
}
private static int postOrder
(int limit,
int depth,
int next, Map
<Integer, Integer
> indices,
int[] ans
) { if (depth == limit) {
return next;
}
// left
int left = postOrder(limit, depth + 1, next, indices, ans);
next = left < 0 ? -left : left;
int right = postOrder(limit, depth + 1, next, indices, ans);
next = right < 0 ? -right : right;
int me = next + 1;
if (left < 0) {
int i = indices.get(-left);
ans[i] = me;
}
if (right < 0) {
int i = indices.get(-right);
ans[i] = me;
}
return indices.containsKey(me) ? -me : me;
}
public static void main
(String[] args
) { testRun(3, new int[] { 7, 3, 5, 1 }, new int[] { -1, 7, 6, 3 });
testRun(5, new int[] { 19, 14, 28 }, new int[] { 21, 15, 29 });
}
private static void testRun(int height, int[] input, int[] output) {
int[] ans = answer(height, input);
int[] ans2 = answerToo(height, input);
System.
out.
printf("Input height %d and nodes %s:\n%s\n%s\n", height,
Arrays.
toString(input
),
}
}
aW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkludFN0cmVhbTsKCmNsYXNzIEFuc3dlciB7CiAgICAKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBwYXJlbnQoaW50IGhlaWdodCwgaW50IG5vZGUpIHsKICAgICAgICBpbnQgc2l6ZSA9IChpbnQpTWF0aC5wb3coMiwgaGVpZ2h0KSAtIDE7CiAgICAgICAgCiAgICAgICAgaWYgKG5vZGUgPT0gc2l6ZSkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGludCBiZWZvcmUgPSAwOwogICAgICAgIGRvIHsKICAgICAgICAgICAgaWYgKHNpemUgPT0gMCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNpemUgPj4+PSAxOwogICAgICAgICAgICBpbnQgbGVmdCA9IGJlZm9yZSArIHNpemU7CiAgICAgICAgICAgIGludCByaWdodCA9IGxlZnQgKyBzaXplOwogICAgICAgICAgICBpbnQgbWUgPSByaWdodCArIDE7CiAgICAgICAgICAgIGlmIChsZWZ0ID09IG5vZGUgfHwgcmlnaHQgPT0gbm9kZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG1lOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChub2RlID4gbGVmdCkgewogICAgICAgICAgICAgICAgYmVmb3JlID0gbGVmdDsKICAgICAgICAgICAgfQogICAgICAgIH0gd2hpbGUgKHRydWUpOwogICAgICAgIAogICAgfQogICAgCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludFtdIGFuc3dlclRvbyhpbnQgaGVpZ2h0LCBpbnRbXSBub2RlcykgewogICAgICAgIHJldHVybiBJbnRTdHJlYW0ub2Yobm9kZXMpLm1hcChuIC0+IHBhcmVudChoZWlnaHQsIG4pKS50b0FycmF5KCk7CiAgICB9CiAgICAKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50W10gYW5zd2VyKGludCBoZWlnaHQsIGludFtdIG5vZGVzKSB7CiAgICAgICAgaW50W10gYW5zID0gbmV3IGludFtub2Rlcy5sZW5ndGhdOwogICAgICAgIE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBpbmRpY2VzID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgIEludFN0cmVhbS5yYW5nZSgwLCBub2Rlcy5sZW5ndGgpLmZvckVhY2hPcmRlcmVkKGkgLT4gaW5kaWNlcy5wdXQobm9kZXNbaV0sIGkpKTsKICAgICAgICBpbnQgbmV4dCA9IHBvc3RPcmRlcihoZWlnaHQsIDAsIDAsIGluZGljZXMsIGFucyk7CiAgICAgICAgaWYgKG5leHQgPCAwKSB7CiAgICAgICAgICAgIGludCBpID0gaW5kaWNlcy5nZXQoLW5leHQpOwogICAgICAgICAgICBhbnNbaV0gPSAtMTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFuczsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBpbnQgcG9zdE9yZGVyKGludCBsaW1pdCwgaW50IGRlcHRoLCBpbnQgbmV4dCwgTWFwPEludGVnZXIsIEludGVnZXI+IGluZGljZXMsIGludFtdIGFucykgewogICAgICAgIGlmIChkZXB0aCA9PSBsaW1pdCkgewogICAgICAgICAgICByZXR1cm4gbmV4dDsKICAgICAgICB9CiAgICAgICAgLy8gbGVmdAogICAgICAgIGludCBsZWZ0ID0gcG9zdE9yZGVyKGxpbWl0LCBkZXB0aCArIDEsIG5leHQsIGluZGljZXMsIGFucyk7CiAgICAgICAgbmV4dCA9IGxlZnQgPCAwID8gLWxlZnQgOiBsZWZ0OwogICAgICAgIGludCByaWdodCA9IHBvc3RPcmRlcihsaW1pdCwgZGVwdGggKyAxLCBuZXh0LCBpbmRpY2VzLCBhbnMpOwogICAgICAgIG5leHQgPSByaWdodCA8IDAgPyAtcmlnaHQgOiByaWdodDsKCiAgICAgICAgaW50IG1lID0gbmV4dCArIDE7CgogICAgICAgIGlmIChsZWZ0IDwgMCkgewogICAgICAgICAgICBpbnQgaSA9IGluZGljZXMuZ2V0KC1sZWZ0KTsKICAgICAgICAgICAgYW5zW2ldID0gbWU7CiAgICAgICAgfQogICAgICAgIGlmIChyaWdodCA8IDApIHsKICAgICAgICAgICAgaW50IGkgPSBpbmRpY2VzLmdldCgtcmlnaHQpOwogICAgICAgICAgICBhbnNbaV0gPSBtZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpbmRpY2VzLmNvbnRhaW5zS2V5KG1lKSA/IC1tZSA6IG1lOwoKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgdGVzdFJ1bigzLCBuZXcgaW50W10geyA3LCAzLCA1LCAxIH0sIG5ldyBpbnRbXSB7IC0xLCA3LCA2LCAzIH0pOwogICAgICAgIHRlc3RSdW4oNSwgbmV3IGludFtdIHsgMTksIDE0LCAyOCB9LCBuZXcgaW50W10geyAyMSwgMTUsIDI5IH0pOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdFJ1bihpbnQgaGVpZ2h0LCBpbnRbXSBpbnB1dCwgaW50W10gb3V0cHV0KSB7CiAgICAgICAgaW50W10gYW5zID0gYW5zd2VyKGhlaWdodCwgaW5wdXQpOwogICAgICAgIGludFtdIGFuczIgPSBhbnN3ZXJUb28oaGVpZ2h0LCBpbnB1dCk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGYoIklucHV0IGhlaWdodCAlZCBhbmQgbm9kZXMgJXM6XG4lc1xuJXNcbiIsIGhlaWdodCwgQXJyYXlzLnRvU3RyaW5nKGlucHV0KSwKICAgICAgICAgICAgICAgIEFycmF5cy50b1N0cmluZyhhbnMpLCBBcnJheXMudG9TdHJpbmcoYW5zMiksIEFycmF5cy50b1N0cmluZyhvdXRwdXQpKTsKICAgIH0KCn0K