Advertisement
Guest User

Untitled

a guest
Jun 25th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.58 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. #!/bin/python
  4.  
  5. from collections import *
  6.  
  7.  
  8. def gen_primes():
  9. D = {}
  10. q = 2
  11.  
  12. while True:
  13. if q not in D:
  14. yield q
  15. D[q * q] = [q]
  16. else:
  17. for p in D[q]:
  18. D.setdefault(p + q, []).append(p)
  19. del D[q]
  20.  
  21. q += 1
  22.  
  23.  
  24. # precompute prime numbers smaller than sqrt(10**9)
  25. prime_gen = gen_primes()
  26. primes = [next(prime_gen) for _ in xrange(3500)]
  27.  
  28.  
  29. # enhanced trial division method using precomputed prime numbers
  30. def trial_division(n):
  31. a = set()
  32.  
  33. while n % 2 == 0:
  34. a.add(2)
  35. n /= 2
  36.  
  37. i = 1
  38. f = primes[i]
  39.  
  40. while f * f <= n:
  41. if n % f == 0:
  42. a.add(f)
  43. n /= f
  44. else:
  45. i += 1
  46. f = primes[i]
  47.  
  48. if n != 1:
  49. a.add(n)
  50.  
  51. return a
  52.  
  53.  
  54. def bfs(graph, cap_edges, level, s, t):
  55. queue = deque()
  56. queue.append(s)
  57.  
  58. level[s] = 1
  59.  
  60. while queue:
  61. u = queue.popleft()
  62.  
  63. for v, eid, _ in graph[u]:
  64. if level[v] == 0 and cap_edges[eid] > 0:
  65. level[v] = level[u] + 1
  66. queue.append(v)
  67.  
  68. return level[t] > 0
  69.  
  70.  
  71. def dfs(graph, ptr, cap_edges, level, u, s, t):
  72. if u == t:
  73. return 1
  74.  
  75. adj = graph[u]
  76. ind = ptr[u]
  77.  
  78. i = ind
  79. n = len(adj)
  80. while i < n:
  81. v, eid, eid_b = adj[i]
  82. ptr[u] = i
  83. i += 1
  84.  
  85. if (level[v] == level[u] + 1) and cap_edges[eid] > 0:
  86. f = dfs(graph, ptr, cap_edges, level, v, s, t)
  87. if f > 0:
  88. cap_edges[eid] -= 1
  89. cap_edges[eid_b] += 1
  90. return f
  91.  
  92. return 0
  93.  
  94.  
  95. # solve the max-flow problem using the Dinic algorithm
  96. def max_flow(graph, cap_edges, s, t):
  97. n = len(graph)
  98. level = [0] * n
  99. ptr = [0] * n
  100.  
  101. flow = 0
  102. while bfs(graph, cap_edges, level, s, t):
  103. f = dfs(graph, ptr, cap_edges, level, s, s, t)
  104.  
  105. while f > 0:
  106. flow += f
  107. f = dfs(graph, ptr, cap_edges, level, s, s, t)
  108.  
  109. level = [0] * n
  110. ptr = [0] * n
  111.  
  112. return flow
  113.  
  114.  
  115. def computer_game(n, A, B):
  116.  
  117. start_node = 0
  118. end_node = 1
  119.  
  120. graph = defaultdict(list)
  121. cap_edges = []
  122. node_count = 2
  123. edges_count = 0
  124. prime_nodes_map = {}
  125.  
  126. for value in A:
  127. current_node = node_count
  128.  
  129. graph[start_node].append((current_node, edges_count, edges_count+1))
  130. cap_edges.append(1)
  131. graph[current_node].append((start_node, edges_count+1, edges_count))
  132. cap_edges.append(0)
  133. edges_count += 2
  134. node_count += 1
  135.  
  136. factors = trial_division(value)
  137.  
  138. for p in factors:
  139. if p not in prime_nodes_map:
  140. prime_nodes_map[p] = node_count
  141. node_count += 1
  142.  
  143. p_node = prime_nodes_map[p]
  144. graph[current_node].append((p_node, edges_count, edges_count+1))
  145. cap_edges.append(1)
  146.  
  147. graph[p_node].append((current_node, edges_count+1, edges_count))
  148. cap_edges.append(0)
  149. edges_count += 2
  150.  
  151. for value in B:
  152. current_node = node_count
  153.  
  154. graph[current_node].append((end_node, edges_count, edges_count+1))
  155. cap_edges.append(1)
  156.  
  157. graph[end_node].append((current_node, edges_count+1, edges_count))
  158. cap_edges.append(0)
  159. edges_count += 2
  160. node_count += 1
  161.  
  162. factors = trial_division(value)
  163. for p in factors:
  164. if p not in prime_nodes_map:
  165. prime_nodes_map[p] = node_count
  166. node_count += 1
  167.  
  168. p_node = prime_nodes_map[p]
  169. graph[p_node].append((current_node, edges_count, edges_count+1))
  170. cap_edges.append(1)
  171.  
  172. graph[current_node].append((p_node, edges_count+1, edges_count))
  173. cap_edges.append(0)
  174. edges_count += 2
  175.  
  176. result = max_flow(graph, cap_edges, start_node, end_node)
  177. print(result)
  178.  
  179.  
  180. if __name__ == '__main__':
  181. n = int(raw_input())
  182.  
  183. a = map(int, raw_input().rstrip().split())
  184.  
  185. b = map(int, raw_input().rstrip().split())
  186.  
  187. computer_game(n, a, b)
  188.  
  189. def trial_division(n):
  190. a = set()
  191.  
  192. while n % 2 == 0:
  193. a.add(2)
  194. n //= 2
  195.  
  196. for p in primes:
  197. if p * p > n:
  198. break
  199.  
  200. while n % p == 0:
  201. a.add(p)
  202. n //= p
  203.  
  204. if n != 1:
  205. a.add(n)
  206.  
  207. return a
  208.  
  209. primesWithSquares = [(p, p*p) for p in primes]
  210.  
  211. for p, p2 in primesWithSquares:
  212. if p2 > n:
  213. break
  214.  
  215. while n % p == 0:
  216. a.add(p)
  217. n //= p
  218.  
  219. def trial_division(n):
  220. a = []
  221.  
  222. if n & 1 == 0:
  223. a.append(2)
  224. n //= 2
  225. while n & 1 == 0:
  226. n //= 2
  227.  
  228. for p, p2 in primesWithSquares:
  229. if p2 > n:
  230. break
  231.  
  232. if n % p == 0:
  233. a.append(p)
  234. n //= p
  235. while n % p == 0:
  236. n //= p
  237.  
  238. if n != 1:
  239. a.append(n)
  240.  
  241. return a
  242.  
  243. def add_edge(u, v, direction):
  244. graph[u].append((v, edges_count, edges_count+1))
  245. cap_edges.append(direction)
  246. graph[v].append((u, edges_count+1, edges_count))
  247. cap_edges.append(1 - direction)
  248. edges_count += 2
  249.  
  250. def new_node():
  251. node_count += 1
  252. return node_count - 1
  253.  
  254. def add_half_graph(values, end_node, direction):
  255. for value in values:
  256. current_node = new_node()
  257.  
  258. add_edge(end_node, current_node, direction)
  259.  
  260. for p in trial_division(value):
  261. if p not in prime_nodes_map:
  262. prime_nodes_map[p] = new_node()
  263.  
  264. add_edge(current_node, prime_nodes_map[p], direction)
  265.  
  266. add_half_graph(A, start_node, 1)
  267. add_half_graph(B, end_node, 0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement