fork download
  1. import math
  2.  
  3. # Đọc dữ liệu nhanh từ input
  4. d = []
  5. try:
  6. while True:
  7. d.extend(input().split())
  8. except Exception:
  9. pass
  10.  
  11. if d:
  12. p = 0
  13. t = int(d[p])
  14. p += 1
  15.  
  16. for _ in range(t):
  17. n = int(d[p])
  18. p += 1
  19.  
  20. # Sửa lỗi: Thêm phần tử [0] ở đầu mảng
  21. a = [0] + [int(x) for x in d[p : p + n]]
  22. p += n
  23.  
  24. b = [0] + [int(x) for x in d[p : p + n]]
  25. p += n
  26.  
  27. # G: Danh sách kề của cây
  28. G = [[] for _ in range(n + 1)]
  29. for _ in range(n - 1):
  30. u, v = int(d[p]), int(d[p + 1])
  31. p += 2
  32. G[u].append(v)
  33. G[v].append(u)
  34.  
  35. # Sửa lỗi: Khởi tạo mảng cha P và hàng đợi Q = [1]
  36. P = [0] * (n + 1)
  37. C = [[] for _ in range(n + 1)]
  38. Q = [1]
  39.  
  40. h = 0
  41. while h < len(Q):
  42. u = Q[h]
  43. h += 1
  44. for v in G[u]:
  45. if v != P[u]:
  46. P[v] = u
  47. C[u].append(v)
  48. Q.append(v)
  49.  
  50. # g: Bước nhảy hiệu dụng của mỗi nút
  51. g = [0] * (n + 1)
  52. ans = 0
  53.  
  54. # Duyệt ngược từ lá lên gốc (Bottom-up)
  55. for u in reversed(Q):
  56. if not C[u]:
  57. g[u] = b[u]
  58. else:
  59. s = sum(a[v] for v in C[u])
  60. cur = math.gcd(b[u], s)
  61. for v in C[u]:
  62. # CHỈ TÍNH g[v] NẾU NÚT CON CÓ THỂ BIẾN ĐỔI (g[v] < b[v])
  63. if g[v] < b[v]:
  64. cur = math.gcd(cur, g[v])
  65. g[u] = cur
  66.  
  67. # Tính giá trị lớn nhất đạt được tại nút u và cộng vào kết quả
  68. ans += b[u] - 1 - ((b[u] - 1 - a[u]) % g[u])
  69.  
  70. print(ans)
  71.  
Success #stdin #stdout 0.06s 14128KB
stdin
8
1
3
7
2
0 3
5 4
1 2
3
0 2 3
7 3 4
1 2
2 3
3
0 0 1
5 2 2
1 2
2 3
4
1 2 3 4
10 3 4 5
1 2
1 3
1 4
3
0 1 3
10 2 4
1 2
1 3
5
0 0 1 2 3
12 6 9 3 4
1 2
1 3
2 4
3 5
4
0 999999999 999999999 999999999
1000000000 1000000000 1000000000 1000000000
1 2
1 3
1 4
stdout
3
7
11
6
18
12
27
3999999996