Skip to content

Commit 23b5994

Browse files
solves kittys calculations on a tree
1 parent 4311174 commit 23b5994

File tree

6 files changed

+240
-212
lines changed

6 files changed

+240
-212
lines changed
+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
// Solution Provided by Jesse Sparks
2+
// See GitHub: https://github.com/jsparks125
3+
4+
#include <chrono>
5+
#include <cmath>
6+
#include <cstdio>
7+
#include <map>
8+
#include <queue>
9+
#include <set>
10+
#include <stack>
11+
#include <tuple>
12+
#include <vector>
13+
#include <iostream>
14+
#include <fstream>
15+
#include <algorithm>
16+
#include <unordered_map>
17+
#include <string>
18+
19+
int max_depth = 0;
20+
21+
struct node
22+
{
23+
int value;
24+
int depth;
25+
node* parent;
26+
27+
node(int v, int d, node* p)
28+
{
29+
value = v;
30+
depth = d;
31+
parent = p;
32+
}
33+
34+
node()
35+
{
36+
value = -1;
37+
depth = -1;
38+
}
39+
};
40+
41+
struct subtree
42+
{
43+
int root_node;
44+
int depth;
45+
int next_calc_depth = -1;
46+
unsigned long long next_calc = 0;
47+
unsigned long long next_sum = 0;
48+
49+
subtree()
50+
{}
51+
52+
subtree(int d)
53+
{
54+
depth = d;
55+
}
56+
57+
subtree(int cn, int d)
58+
{
59+
root_node = cn;
60+
depth = d;
61+
next_calc_depth = d;
62+
}
63+
};
64+
65+
std::unordered_map<int, node> nodes;
66+
67+
int main()
68+
{
69+
int num_nodes, num_sets;
70+
std::cin >> num_nodes >> num_sets;
71+
int child_node, parent_node;
72+
73+
std::vector<std::pair<int, int>> node_list;
74+
for (int i = 1; i < num_nodes; i++)
75+
{
76+
std::cin >> child_node >> parent_node;
77+
if (parent_node > child_node)
78+
node_list.push_back(std::pair<int, int>(child_node, parent_node));
79+
else
80+
node_list.push_back(std::pair<int, int>(parent_node, child_node));
81+
}
82+
83+
std::pair<int, int> first_node_pair = *(node_list.begin());
84+
parent_node = first_node_pair.first;
85+
child_node = first_node_pair.second;
86+
nodes[parent_node] = node(parent_node, 0, nullptr);
87+
nodes[child_node] = node(child_node, 1, &nodes[parent_node]);
88+
89+
for (auto it = std::next(node_list.begin()); it != node_list.end(); ++it)
90+
{
91+
parent_node = it->first;
92+
child_node = it->second;
93+
node* parent = &nodes[parent_node];
94+
int parent_depth = parent->depth;
95+
int current_depth = parent_depth + 1;
96+
97+
if (current_depth > max_depth)
98+
max_depth = current_depth;
99+
100+
nodes[child_node] = node(child_node, current_depth, parent);
101+
}
102+
103+
for (int i = 0; i < num_sets; i++)
104+
{
105+
int n;
106+
std::cin >> n;
107+
108+
if (n > 1)
109+
{
110+
int loadTime = 0;
111+
112+
std::map<int, subtree> subtrees;
113+
std::map<int, std::map<int, node>> nodes_by_depth;
114+
115+
unsigned long long int new_kitty_sum = 0;
116+
int subtree_max_depth = 0;
117+
118+
//Load nodes from the current set and store them by their depth
119+
for (int j = 0; j < n; j++)
120+
{
121+
int current_node_key;
122+
std::cin >> current_node_key;
123+
node current_node = nodes[current_node_key];
124+
125+
int current_depth = current_node.depth;
126+
if (current_depth > subtree_max_depth)
127+
subtree_max_depth = current_depth;
128+
129+
nodes_by_depth[current_depth][current_node.value] = current_node;
130+
}
131+
132+
//Start at the bottom of the tree and work upward, combining nodes as they hit their common ancestor
133+
for (int j = subtree_max_depth; j > 0; j--)
134+
{
135+
auto process_roots = nodes_by_depth.find(j);
136+
137+
//We can easily shift a node up as long as it is the only node at its current level and there are no nodes directly above it
138+
//This alleviates quite a bit of processing on very deep trees
139+
if (process_roots->second.size() == 1)
140+
{
141+
auto next_roots_iter = nodes_by_depth.find(j - 1);
142+
if (next_roots_iter == nodes_by_depth.end())
143+
{
144+
int shifted = 0;
145+
node current_node = process_roots->second.begin()->second;
146+
int previous_node_value = current_node.value;
147+
while (next_roots_iter == nodes_by_depth.end() && (j - shifted) > 0)
148+
{
149+
shifted++;
150+
next_roots_iter = nodes_by_depth.find(j - shifted);
151+
if (next_roots_iter == nodes_by_depth.end())
152+
{
153+
previous_node_value = current_node.parent->value;
154+
current_node.parent = current_node.parent->parent;
155+
}
156+
}
157+
nodes_by_depth[j - (shifted - 1)].insert(std::pair<int, node>(previous_node_value, current_node));
158+
process_roots = nodes_by_depth.find(j - (shifted - 1));
159+
j -= (shifted - 1);
160+
}
161+
}
162+
163+
//Check all of the roots at the current level to see if they have a common ancestor or if their parent exists at the next level
164+
//If so, they can be combined
165+
for (auto root_iter = process_roots->second.begin(); root_iter != process_roots->second.end(); ++root_iter)
166+
{
167+
node current_node = root_iter->second;
168+
if (current_node.parent == nullptr)
169+
break;
170+
node* parent_node = current_node.parent;
171+
172+
auto parent_iter = nodes_by_depth[j - 1].find(current_node.parent->value);
173+
if (parent_iter != nodes_by_depth[j - 1].end())
174+
{
175+
subtree* next_root_subtree;
176+
auto next_iter = subtrees.find(parent_iter->second.value);
177+
if (next_iter != subtrees.end())
178+
next_root_subtree = &next_iter->second;
179+
else
180+
{
181+
auto nrs_iter = subtrees.insert(std::pair<int, subtree>(parent_iter->first, subtree(parent_iter->first, j - 1))).first;
182+
next_root_subtree = &(nrs_iter->second);
183+
next_root_subtree->next_calc = (uint64_t(parent_iter->second.depth - (j - 1)) * uint64_t(parent_iter->second.value)) % 1000000007;
184+
next_root_subtree->next_sum = parent_iter->second.value;
185+
nodes_by_depth[j - 1][parent_iter->first].value = parent_iter->first;
186+
}
187+
188+
unsigned long long next_calc = next_root_subtree->next_calc + (next_root_subtree->next_sum * (next_root_subtree->next_calc_depth - (j - 1))) % 1000000007;
189+
unsigned long long next_child_sum = next_root_subtree->next_sum;
190+
next_root_subtree->next_calc = next_calc;
191+
next_root_subtree->next_calc_depth = j - 1;
192+
193+
auto current_iter = subtrees.find(current_node.value);
194+
if (current_iter != subtrees.end())
195+
{
196+
subtree* current_subtree = &current_iter->second;
197+
int current_index = current_subtree->next_calc_depth - (j - 1);
198+
unsigned long long new_sum = next_calc * (current_subtree->next_sum);
199+
unsigned long long current_product = current_subtree->next_calc + (current_subtree->next_sum * uint64_t(current_index)) % 1000000007;
200+
unsigned long long second_sum = next_child_sum * (current_product % 1000000007);
201+
new_kitty_sum += (new_sum % 1000000007) + (second_sum % 1000000007);
202+
next_root_subtree->next_calc += (current_product % 1000000007);
203+
next_root_subtree->next_calc %= 1000000007;
204+
next_root_subtree->next_sum += current_subtree->next_sum;
205+
}
206+
else
207+
{
208+
int current_depth = current_node.depth;
209+
int current_index = current_depth - (j - 1);
210+
int current_sum = current_node.value;
211+
unsigned long long new_sum = next_calc * uint64_t(current_sum);
212+
unsigned long long current_product = uint64_t(current_sum) * uint64_t(current_index);
213+
unsigned long long second_sum = next_child_sum * (current_product % 1000000007);
214+
new_kitty_sum += (new_sum % 1000000007) + (second_sum % 1000000007);
215+
int new_index = current_depth - next_root_subtree->depth;
216+
next_root_subtree->next_calc += (current_product % 1000000007);
217+
next_root_subtree->next_calc %= 1000000007;
218+
next_root_subtree->next_sum += uint64_t(current_sum);
219+
}
220+
}
221+
else
222+
{
223+
int new_root_depth = j - 1;
224+
current_node.parent = parent_node->parent;
225+
nodes_by_depth[new_root_depth][parent_node->value] = current_node;
226+
}
227+
}
228+
}
229+
230+
std::cout << new_kitty_sum % 1000000007 << std::endl;
231+
}
232+
else
233+
{
234+
std::cin >> n;
235+
std::cout << 0 << std::endl;
236+
}
237+
}
238+
239+
return 0;
240+
}

β€Žtrees-generic/src/KittysCalculationsOnTree.java

-29
This file was deleted.

β€Žtrees/src/TopView.java

-98
This file was deleted.

β€Žtrees/src/TopView_Editorial.java

-27
This file was deleted.

0 commit comments

Comments
Β (0)