Skip to content
Programming101
Programmingoneonone

Learn everything about programming

  • Home
  • CS Subjects
    • IoT – Internet of Things
    • Digital Communication
    • Human Values
  • Programming Tutorials
    • C Programming
    • Data structures and Algorithms
    • 100+ Java Programs
    • 100+ C Programs
  • HackerRank Solutions
    • HackerRank Algorithms Solutions
    • HackerRank C problems solutions
    • HackerRank C++ problems solutions
    • HackerRank Java problems solutions
    • HackerRank Python problems solutions
Programming101
Programmingoneonone

Learn everything about programming

HackerEarth Joseph and Tree problem solution

YASH PAL, 31 July 2024
In this HackerEarth Joseph and Tree problem solution, Joseph loves games about a tree! His friend Nick invented a game for him!
Initially, there is a rooted weighted tree with N vertices numbered 1 … N. Nick guarantees that the tree is connected, and there is a unique path between any vertices! Also he gave us Q queries on it of the following type:
  1. v and k: Let S denote the sorted (nondecreasing order) array of shortest distances from v to any other vertex from subtree rooted v. Answer will be kth element of S. If such a number does not exist, i.e. the S has less than k elements, answer is 1. Note that v is not included in his own subtree.
All the indices in the queries are 1-based. The root of the tree is node 1.
But it turns out, Joseph has an exam tomorrow, and he doesn’t have time for playing a game! And he asks your help!
HackerEarth Joseph and Tree problem solution

Topics we are covering

Toggle
  • HackerEarth Joseph and Tree problem solution.
    • Second solution

HackerEarth Joseph and Tree problem solution.

#include <bits/stdc++.h>

#define pb push_back
#define f first
#define s second
#define mp make_pair
#define sz(a) int((a).size())
#ifdef _WIN32
# define I64 "%I64d"
#else
# define I64 "%lld"
#endif
#define fname "."
#define pi pair < int, int >
#define pp pop_back

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const int MAX_N = (int)1e5 + 123;
const double eps = 1e-6;
const int inf = (int)1e9 + 123;

using namespace std;

int n, q;
vector < pi > g[MAX_N];

struct tree {
int sum, l, r;
tree() : sum(0), l(-1), r(-1) {}
};

vector < tree > t;

int update(int x, int v, int tl = 0, int tr = n - 1) {
int now = sz(t);
t.pb(tree());
if (v != -1)
t[now] = t[v];
if (tl == tr) {
t[now].sum++;
return now;
}
int tm = (tl + tr) / 2;
if (x <= tm) {
int son = update(x, (v == -1 ? -1 : t[v].l), tl, tm);
t[now].l = son;
}
else {
int son = update(x, (v == -1 ? -1 : t[v].r), tm + 1, tr);
t[now].r = son;
}
t[now].sum = 0;
if (t[now].l != -1)
t[now].sum += t[t[now].l].sum;
if (t[now].r != -1)
t[now].sum += t[t[now].r].sum;
return now;
}

int find_kth(int L, int R, int k, int tl = 0, int tr = n - 1) {
if (tl == tr)
return tl;
int tm = (tl + tr) / 2;
int left = 0;
if (R != -1 && t[R].l != -1)
left += t[t[R].l].sum;
if (L != -1 && t[L].l != -1)
left -= t[t[L].l].sum;

if (k <= left)
return find_kth((L == -1 ? -1 : t[L].l), (R == -1 ? -1 : t[R].l), k, tl, tm);
k -= left;
return find_kth((L == -1 ? -1 : t[L].r), (R == -1 ? -1 : t[R].r), k, tm + 1, tr);
}

vector < int > st;
ll dist[MAX_N];
int l[MAX_N], r[MAX_N];

void dfs(int v, int pr = -1, ll all = 0) {
dist[v] = all;
l[v] = sz(st);
st.pb(v);
for (auto to : g[v])
if (to.f != pr)
dfs(to.f, v, all + to.s);
r[v] = sz(st) - 1;
}

int root[MAX_N];
vector < ll > uniq;

ll get(int v, int k) {
int sz = r[v] - l[v];
if (k > sz)
return -1;
return uniq[find_kth(root[l[v]], root[r[v]], k)] - uniq[dist[v]];
}

int main() {
#ifdef Nick
freopen(fname"in", "r", stdin);
freopen(fname"out", "w", stdout);
#endif
scanf("%d", &n);
for (int i = 1, u, v, w; i < n; i++) {
scanf("%d%d%d", &u, &v, &w);
g[u].pb(mp(v, w)), g[v].pb(mp(u, w));
}

dfs(1);

for (int i = 1; i <= n; i++)
uniq.pb(dist[i]);
sort(uniq.begin(), uniq.end());
uniq.resize(unique(uniq.begin(), uniq.end()) - uniq.begin());
for (int i = 1; i <= n; i++)
dist[i] = lower_bound(uniq.begin(), uniq.end(), dist[i]) - uniq.begin();

for (int i = 0, last = -1; i < sz(st); i++) {
last = root[i] = update(dist[st[i]], last);
}

int query;
scanf("%d", &query);
for (int i = 1, v, k; i <= query; i++) {
scanf("%d%d", &v, &k);
printf(I64"n", get(v, k));
}

return 0;
}

Second solution

import java.io.*;
import java.util.*;

public class AugClashJosephAndTree {

static int N;
static ArrayList<Integer> adj[], weight[];
static long depth[];
static int dfsOrder[];
static int timeIn[], timeOut[];
static int time;
static TreeMap<Long, Integer> dist;
static long revMap[];
static ArrayList<Node> nodes;
static int root[];

@SuppressWarnings("unchecked")
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
PrintWriter out = new PrintWriter(System.out);

N = in.nextInt();
check(1, N, (int) 1e5);

adj = new ArrayList[N + 1];
weight = new ArrayList[N + 1];

for (int i = 1; i <= N; i++) {
adj[i] = new ArrayList<Integer>();
weight[i] = new ArrayList<Integer>();
}

for (int i = 1; i < N; i++) {
int a = in.nextInt();
int b = in.nextInt();
int w = in.nextInt();
check(1, a, N);
check(1, b, N);
check(1, w, (int) 1e9);
adj[a].add(b);
weight[a].add(w);
adj[b].add(a);
weight[b].add(w);
}

depth = new long[N + 1];
timeIn = new int[N + 1];
timeOut = new int[N + 1];
dfsOrder = new int[N + 1];
time = 0;
dfs(1, -1, 0);

dist = new TreeMap<Long, Integer>();
for (int i = 1; i <= N; i++)
dist.put(depth[i], 0);

revMap = new long[dist.size() + 1];

int cnt = 0;
for (long x : dist.keySet()) {
dist.put(x, ++cnt);
revMap[cnt] = x;
}

root = new int[N + 1];
root[0] = 0;

nodes = new ArrayList<Node>();
nodes.add(new Node());

// dist.get(depth[i]) returns rank of depth[i]
for (int i = 1; i <= N; i++) {
root[i] = update(root[i - 1], 1, cnt, dist.get(depth[dfsOrder[i]]));
}

int Q = in.nextInt();
check(1, Q, (int) 1e5);

while (Q-- > 0) {
int v = in.nextInt();
int k = in.nextInt();
check(1, v, N);
check(1, k, (int) 1e9);
out.println(solve(v, k, cnt));
}

out.close();
}

static long solve(int v, int k, int cnt) {
int size = timeOut[v] - timeIn[v];
if (size < k)
return -1;
int ans = findKth(1, cnt, root[timeIn[v]], root[timeOut[v]], k);
return revMap[ans] - depth[v];
}

static int findKth(int start, int end, int leftRoot, int rightRoot, int k) {
if (start == end)
return start;
int mid = (start + end) >> 1;
int leftSum = sum(left(rightRoot)) - sum(left(leftRoot)); //number of nodes in [start,mid]
if (leftSum >= k)
return findKth(start, mid, left(leftRoot), left(rightRoot), k);
else
return findKth(mid + 1, end, right(leftRoot), right(rightRoot), k - leftSum);
}

static int update(int prevRoot, int start, int end, int x) {
Node now = new Node();
now.sum = sum(prevRoot);
now.left = left(prevRoot);
now.right = right(prevRoot);
nodes.add(now);

int idx = nodes.size() - 1;

if (start == end) {
now.sum++;
return idx;
}

int mid = (start + end) >> 1;

if (x <= mid) {
int leftSon = left(prevRoot);
now.left = update(leftSon, start, mid, x);
}

else {
int rightSon = right(prevRoot);
now.right = update(rightSon, mid + 1, end, x);
}

now.sum = sum(now.left) + sum(now.right);
return idx;
}

static void dfs(int curr, int parent, long pathLength) {
depth[curr] = pathLength;
timeIn[curr] = ++time;
dfsOrder[time] = curr;
for (int i = 0; i < adj[curr].size(); i++) {
int child = adj[curr].get(i);
int edgeWeight = weight[curr].get(i);
if (child != parent) {
dfs(child, curr, pathLength + edgeWeight);
}
}
timeOut[curr] = time;
}

static class Node {
int sum, left, right;

Node() {
sum = 0;
left = -1;
right = -1;
}
}

static int sum(int idx) {
return idx == -1 ? 0 : nodes.get(idx).sum;
}

static int left(int idx) {
return idx == -1 ? -1 : nodes.get(idx).left;
}

static int right(int idx) {
return idx == -1 ? -1 : nodes.get(idx).right;
}

static void check(int start, int key, int end) {
if (key < start || key > end)
throw new RuntimeException();
}

static class InputReader {

private final InputStream stream;
private final byte[] buf = new byte[8192];
private int curChar, snumChars;
private SpaceCharFilter filter;

public InputReader(InputStream stream) {
this.stream = stream;
}

public int snext() {
if (snumChars == -1)
throw new InputMismatchException();
if (curChar >= snumChars) {
curChar = 0;
try {
snumChars = stream.read(buf);
} catch (IOException e) {
throw new InputMismatchException();
}
if (snumChars <= 0)
return -1;
}
return buf[curChar++];
}

public int nextInt() {
int c = snext();
while (isSpaceChar(c)) {
c = snext();
}
int sgn = 1;
if (c == '-') {
sgn = -1;
c = snext();
}
int res = 0;
do {
if (c < '0' || c > '9')
throw new InputMismatchException();
res *= 10;
res += c - '0';
c = snext();
} while (!isSpaceChar(c));
return res * sgn;
}

public boolean isSpaceChar(int c) {
if (filter != null)
return filter.isSpaceChar(c);
return c == ' ' || c == 'n' || c == 'r' || c == 't' || c == -1;
}

public interface SpaceCharFilter {
public boolean isSpaceChar(int ch);
}
}
}
coding problems solutions

Post navigation

Previous post
Next post
  • Automating Image Format Conversion with Python: A Complete Guide
  • HackerRank Separate the Numbers solution
  • How AI Is Revolutionizing Personalized Learning in Schools
  • GTA 5 is the Game of the Year for 2024 and 2025
  • Hackerrank Day 5 loops 30 days of code solution
How to download udemy paid courses for free

Pages

  • About US
  • Contact US
  • Privacy Policy

Programing Practice

  • C Programs
  • java Programs

HackerRank Solutions

  • C
  • C++
  • Java
  • Python
  • Algorithm

Other

  • Leetcode Solutions
  • Interview Preparation

Programming Tutorials

  • DSA
  • C

CS Subjects

  • Digital Communication
  • Human Values
  • Internet Of Things
  • YouTube
  • LinkedIn
  • Facebook
  • Pinterest
  • Instagram
©2025 Programmingoneonone | WordPress Theme by SuperbThemes