diff --git a/asecbadge.py b/asecbadge.py new file mode 100644 index 0000000..59bc7a2 --- /dev/null +++ b/asecbadge.py @@ -0,0 +1,42 @@ +from collections import deque, defaultdict +from intset import IntSet + +N, L, B = map(int, input().split()) + +S, D = map(int, input().split()) + +rooms = defaultdict(dict) + +ALL = IntSet(1, B + 1) +NONE = IntSet() + +for i in range(L): + a, b, x, y = map(int, input().split()) + rooms[a][b] = IntSet(x, y + 1) + +ranges = defaultdict(lambda: NONE) +ranges[S] = ALL + +q = deque([S]) + +while q: + if len(ranges[D]) == B: + break + + curr = q.pop() + + # if curr == D: + # continue + + for neighbor, r in rooms[curr].items(): + old = ranges[neighbor] + new = ranges[neighbor] | ranges[curr] & r + if old != new: + # try: + # q.remove(neighbor) + # except ValueError: + # pass + q.append(neighbor) + ranges[neighbor] = new + +print(len(ranges[D])) diff --git a/asecbadge_back.py b/asecbadge_back.py new file mode 100644 index 0000000..066a310 --- /dev/null +++ b/asecbadge_back.py @@ -0,0 +1,42 @@ +from collections import deque, defaultdict +from intset import IntSet + +N, L, B = map(int, input().split()) + +S, D = map(int, input().split()) + +rooms = defaultdict(dict) + +ALL = IntSet(1, B + 1) +NONE = IntSet() + +for i in range(L): + a, b, x, y = map(int, input().split()) + rooms[b][a] = IntSet(x, y + 1) + +ranges = defaultdict(lambda: NONE) +ranges[D] = ALL + +q = [D] + +while q: + # if len(ranges[D]) == B: + # break + + curr = q.pop(0) + + # if curr == D: + # continue + + for neighbor, r in rooms[curr].items(): + old = ranges[neighbor] + new = ranges[neighbor] | (ranges[curr] & r) + if len(old) != len(new): + # try: + # q.remove(neighbor) + # except ValueError: + # pass + q.append(neighbor) + ranges[neighbor] = new + +print(len(ranges[S])) diff --git a/asecbadge_iter.py b/asecbadge_iter.py new file mode 100644 index 0000000..f9e487e --- /dev/null +++ b/asecbadge_iter.py @@ -0,0 +1,50 @@ +from collections import deque, defaultdict + +N, L, B = map(int, input().split()) + +S, D = map(int, input().split()) + +rooms = defaultdict(dict) + +bounds = set() + +for _ in range(L): + a, b, x, y = map(int, input().split()) + rooms[a][b] = x, y + 1 + bounds.add(x) + bounds.add(y + 1) + +total = 0 + +bounds = sorted(bounds) + + +def piecewise(seq): + it = iter(seq) + last = next(it) + for new in it: + yield last, new + last = new + + +for a, b in piecewise(bounds): + q = deque([S]) + visited = [0] * L + + while q: + curr = q.pop() + visited[curr - 1] = 1 + nbors = rooms[curr].items() + + if curr == D: + total += b - a + break + + for n, (la, lb) in nbors: + if visited[n - 1]: + continue + + if a >= la and b <= lb: + q.append(n) + +print(total) diff --git a/intset.py b/intset.py new file mode 100644 index 0000000..db03f6e --- /dev/null +++ b/intset.py @@ -0,0 +1,111 @@ +class IntSet: + def __init__(self, *bounds): + """Bounds must be tuples of the form (a, b), + where integers a <= x < b are included in the set. + """ + + if not bounds: + bounds = [0, 0] + + self.bounds = list(bounds) + + def simplify(self): + i = 0 + while i < len(self.bounds) - 1: + if i % 2 == 0: + if self.bounds[i] >= self.bounds[i + 1]: + del self.bounds[i:i + 2] + else: + i += 1 + else: + if self.bounds[i] >= self.bounds[i + 1]: + if self.bounds[i] >= self.bounds[i + 2]: + del self.bounds[i + 1:i + 3] + else: + del self.bounds[i:i + 2] + else: + i += 1 + + def __or__(self, other): + bounds = None + j = k = 0 + + while j < len(self.bounds) - 1 or k < len(other.bounds) - 1: + if k >= len(other.bounds) - 1: + a, b = self.bounds[j:j + 2] + j += 2 + elif j >= len(self.bounds) - 1: + a, b = other.bounds[k:k + 2] + k += 2 + elif self.bounds[j] < other.bounds[k]: + a, b = self.bounds[j:j + 2] + j += 2 + else: + a, b = other.bounds[k:k + 2] + k += 2 + + if a >= b: + continue + + if not bounds: + bounds = [a, b] + continue + + e = bounds[-1] + + if e >= a: + if e >= b: + continue + bounds[-1] = b + else: + bounds.append(a) + bounds.append(b) + + if not bounds: + bounds = [0, 0] + + new = IntSet() + new.bounds = bounds + return new + + def __and__(self, other): + bounds = [] + + i = j = 0 + while i < len(self.bounds) - 1 and j < len(other.bounds) - 1: + a, b = self.bounds[i:i + 2] + c, d = other.bounds[j:j + 2] + if b > c and a < d: + bounds.append(max(a, c)) + bounds.append(min(b, d)) + if b < d: + i += 2 # toss a b + else: + j += 2 # toss c d + + new = IntSet() + new.bounds = bounds + new.simplify() + return new + + def __eq__(self, other): + return self.bounds == other.bounds + + def __iter__(self): + for a, b in self.pairs: + yield from range(a, b) + + def __len__(self): + return sum(b - a if b > a else 0 for a, b in self.pairs) + + def __lt__(self, other): + return len(self) < len(other) + + @property + def pairs(self): + it = iter(self.bounds) + while True: + yield next(it), next(it) + + def __repr__(self): + return 'U'.join('[{0},{1})'.format(a, b) for a, b in self.pairs) diff --git a/longlong.py b/longlong_fail.py similarity index 100% rename from longlong.py rename to longlong_fail.py diff --git a/make_and_test.py b/make_and_test.py new file mode 100644 index 0000000..5136782 --- /dev/null +++ b/make_and_test.py @@ -0,0 +1,4 @@ +import subprocess + +subprocess.call(['python', 'make_nonsense.py']) +subprocess.call(['python', 'icpc_test.py', 'asecbadge_multi.py', 'security', '5']) diff --git a/make_nonsense.py b/make_nonsense.py new file mode 100644 index 0000000..0c759ed --- /dev/null +++ b/make_nonsense.py @@ -0,0 +1,22 @@ +from itertools import islice, permutations +from random import randint, sample + +N, L, B = 1000, 5000, 100_000_000 +S = D = 0 +while S == D: + S, D = randint(1, N), randint(1, N) + +pairs = sample(list(permutations(range(N), r=2)), L) +rows = [] + +for a, b in pairs: + x = randint(1, B) + y = randint(x, B) + + rows.append((a, b, x, y)) + +with open('test/security/nonsense.in', 'w') as f: + f.writelines(' '.join(map(str, tup)) + '\n' for tup in [(N, L, B), (S, D)] + rows) + +with open('test/security/nonsense.ans', 'w') as f: + f.write('27\n') diff --git a/secbadge.py b/secbadge.py deleted file mode 100644 index 72c00ce..0000000 --- a/secbadge.py +++ /dev/null @@ -1,57 +0,0 @@ -##N, L, B = input().strip().split() -##S, D = input().strip().split() - -class Range(): - - def __init__(self, ranges): - self.ranges = ranges - - def __add__(self, other): - new_ranges = list(self.ranges) - for rang1 in other.ranges: - for i, rang2 in enumerate(new_ranges): - if rang1[0] <= rang2[0] and rang1[1] >= rang2[1]: - new_ranges[i] = rang1 - break - if rang1[0] >= rang2[0] and rang1[1] <= rang2[1]: - break - if rang1[1] >= rang2[0]-1 and rang1[1] <= rang2[1]: - new_ranges[i] = (rang1[0], rang2[1]) - break - if rang1[0] >= rang2[0] and rang1[0] <= rang2[1]+1: - new_ranges[i] = (rang2[0], rang1[1]) - break - else: - new_ranges.append(rang1) - return Range(new_ranges) - - def __mul__(self, other): - new_ranges = [] - for rang1 in other.ranges: - cand = rang1 - for rang2 in self.ranges: - if rang1[0] <= rang2[0] and rang1[1] >= rang2[1]: - cand = rand2 - elif rang1[0] >= rang2[0] and rang1[1] <= rang2[1]: - pass - elif rang1[1] >= rang2[0] and rang1[1] <= rang2[1]: - cand (rang2[0], rang1[1]) - elif rang1[0] >= rang2[0] and rang1[0] <= rang2[1]: - cand = (rang1[0], rang2[1]) - else: - break - else: - new_ranges.append(cand) - return Range(new_ranges) - - def __repr__(self): - return str(*self.ranges) - - def __str__(self): - return str(self.ranges) - -Range.INF = Range([(-float('inf'), float('inf'))]) - -a = Range.INF -b = Range([(3, 4)]) -print(a+b) diff --git a/haiku_sol.py b/solutions/haiku.py similarity index 100% rename from haiku_sol.py rename to solutions/haiku.py diff --git a/longlong_sol.py b/solutions/longlong.py similarity index 100% rename from longlong_sol.py rename to solutions/longlong.py diff --git a/palindrome_sol.py b/solutions/palindrome.py similarity index 100% rename from palindrome_sol.py rename to solutions/palindrome.py diff --git a/purple_rain_sol.py b/solutions/purple_rain.py similarity index 100% rename from purple_rain_sol.py rename to solutions/purple_rain.py diff --git a/rainbowroads_sol.py b/solutions/rainbowroads.py similarity index 100% rename from rainbowroads_sol.py rename to solutions/rainbowroads.py diff --git a/star_arrangements_sol.py b/solutions/star_arrangements.py similarity index 100% rename from star_arrangements_sol.py rename to solutions/star_arrangements.py diff --git a/test/security/custom_1.ans b/test/security/custom_1.ans new file mode 100644 index 0000000..9a03714 --- /dev/null +++ b/test/security/custom_1.ans @@ -0,0 +1 @@ +10 \ No newline at end of file diff --git a/test/security/custom_1.in b/test/security/custom_1.in new file mode 100644 index 0000000..cbc28de --- /dev/null +++ b/test/security/custom_1.in @@ -0,0 +1,6 @@ +3 4 10 +1 3 +1 3 1 5 +1 2 6 10 +2 3 6 10 +3 2 6 10 \ No newline at end of file diff --git a/test/security/custom_2.ans b/test/security/custom_2.ans new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/test/security/custom_2.ans @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/test/security/custom_2.in b/test/security/custom_2.in new file mode 100644 index 0000000..68330b8 --- /dev/null +++ b/test/security/custom_2.in @@ -0,0 +1,5 @@ +4 3 10 +1 4 +1 3 1 5 +1 2 6 10 +2 3 6 10 \ No newline at end of file