-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathlog-set.py
63 lines (55 loc) · 2.21 KB
/
log-set.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# Copyright (c) 2015 kamyu. All rights reserved.
#
# Google Code Jam 2015 Round C - Problem D. Log Set
# https://code.google.com/codejam/contest/4254486/dashboard#s=p3
#
# Time: O(N * (logN)^2), N is sum of F
# Space: O(logN)
#
from math import log
def log_set(P, E, F):
Ei_to_Fi = {E[i]:F[i] for i in xrange(P)}
abs_elements = []
# Total Time: O(1 + 2log2 + (2^2)log(2^2) + ... NlogN) = O(N * (logN)^2)
while len(Ei_to_Fi) > 1: # logN times
Eis = sorted(Ei_to_Fi.keys()) # Time: O(N'logN')
element = Eis[1] - Eis[0]
abs_elements.append(element)
for Ei in Eis:
# Decrease frequencies of E[i] shifted by element by adjusted frequencies.
if (Ei + element) in Ei_to_Fi:
Ei_to_Fi[Ei + element] -= Ei_to_Fi[Ei]
# print element, Eis, Ei_to_Fi
# Keep keys which val > 0 to get new log set without current element.
# This would decrease the sum of frequencies to half of it.
# Time: O(N')
Ei_to_Fi = {Ei:Fi for (Ei,Fi) in Ei_to_Fi.items() if Fi != 0}
Ei_to_Fi = {E[i]:F[i] for i in xrange(P)}
abs_elements = [0] * int(log(F[0], 2)) + abs_elements
base, log_set = 0, []
# print abs_elements[::-1]
# Reversely enumerate abs_elements to achieve the earliest set.
for element in abs_elements[::-1]: # logN times
Eis = sorted(Ei_to_Fi.keys()) # Time: O(N'logN')
for i in Eis:
if (i + element) in Ei_to_Fi:
Ei_to_Fi[i + element] -= Ei_to_Fi[i]
# print element, base, Eis, Ei_to_Fi
Ei_to_Fi = {Ei:Fi for (Ei,Fi) in Ei_to_Fi.items() if Fi != 0}
# If negative of element could be put to set,
# add it to achieve the earliest set.
if base + (-element) in Ei_to_Fi:
log_set.append(-element)
base += -element
else: # element must be positive.
log_set.append(element)
# Nondecreasing order.
log_set.sort()
return " ".join(map(str, log_set))
for case in xrange(input()):
# Read the input.
P = input()
E = map(int, raw_input().strip().split())
F = map(int, raw_input().strip().split())
# print E, F
print "Case #%d: %s" % (case+1, log_set(P, E, F))