fork download
  1. import sys
  2.  
  3. # Tăng giới hạn đệ quy cho an toàn, dù độ sâu cây chỉ khoảng 60
  4. sys.setrecursionlimit(2000)
  5.  
  6. def solve():
  7. # Đọc dữ liệu từ input chuẩn (hoặc thay bằng giá trị cụ thể để test)
  8. # Ví dụ input: 10 2
  9. try:
  10. line = sys.stdin.readline()
  11. if not line:
  12. return
  13. parts = list(map(int, line.split()))
  14. if len(parts) < 2:
  15. return
  16. n = parts[0]
  17. k = parts[1]
  18. except ValueError:
  19. return
  20.  
  21. # Nếu k = 0, theo định nghĩa đường đi 0 cạnh là 1 điểm, có n đường.
  22. # Nhưng thường bài toán đường đi k cạnh yêu cầu k > 0.
  23. if k == 0:
  24. print(n)
  25. return
  26.  
  27. # Cache cho các cây con hoàn hảo
  28. # perfect_memo[h] lưu số đường đi độ dài k trong một cây nhị phân hoàn hảo chiều cao h
  29. perfect_memo = {}
  30.  
  31. def get_perfect_paths(h):
  32. if h < 0: return 0
  33. if h in perfect_memo:
  34. return perfect_memo[h]
  35.  
  36. # Nếu chiều cao cây nhỏ hơn k, không thể chứa đường đi độ dài k?
  37. # Không hẳn, đường đi có thể ngắn hơn chiều cao cây.
  38. # Nhưng ở đây ta đếm đường đi CÓ ĐỘ DÀI ĐÚNG BẰNG k.
  39. # Nếu h < k/2 (xấp xỉ), có thể không có, nhưng để đơn giản ta dùng công thức đệ quy.
  40.  
  41. # Công thức: Tổng đường đi trong cây con trái + cây con phải + đường đi qua gốc
  42. # Trong cây hoàn hảo, cây con trái và phải đều là cây hoàn hảo chiều cao h-1.
  43. cnt = 2 * get_perfect_paths(h - 1)
  44.  
  45. # Cộng thêm các đường đi nhận gốc làm LCA
  46. # 1. Đi thẳng xuống 1 nhánh k bước (chỉ khi h >= k)
  47. # Có 2 nhánh (trái/phải). Mỗi nhánh tại độ sâu k có 2^k nút (nếu gốc là độ sâu 0).
  48. # Trong cây hoàn hảo, số nút ở độ sâu d là 2^d.
  49. if h >= k:
  50. # Gốc -> trái -> ... (k cạnh): có 2^(k-1) đường (vì nút đích ở độ sâu k so với gốc)
  51. # SAI. Nút đích ở độ sâu k. Có 2^k nút ở độ sâu k? Không.
  52. # Trong cây hoàn hảo, ở độ sâu d có 2^d nút.
  53. # Đường đi từ gốc đến 1 nút ở độ sâu k là duy nhất cho mỗi nút đích.
  54. # Vậy có 2^k nút đích -> 2^k đường đi bắt đầu từ gốc?
  55. # Không, từ gốc đi xuống k bước.
  56. # Nút ở độ sâu k có 2^k cái. Mỗi cái tương ứng 1 đường đi từ gốc.
  57. # Vậy có 2^k đường đi bắt đầu từ gốc có độ dài k.
  58. pass
  59.  
  60. # Tính chính xác phần đi qua gốc (LCA):
  61. # Chia k bước thành: x bước bên trái, k-x bước bên phải.
  62. # x chạy từ 0 đến k.
  63. # Nếu x=0: Gốc -> Phải k bước. Số cách = số nút ở độ sâu k-1 bên nhánh phải = 2^(k-1). (Điều kiện k <= h)
  64. # Nếu x=k: Gốc -> Trái k bước. Số cách = số nút ở độ sâu k-1 bên nhánh trái = 2^(k-1). (Điều kiện k <= h)
  65. # Nếu 0 < x < k: Trái (x bước) và Phải (k-x bước).
  66. # Số cách = (nút sâu x-1 bên trái) * (nút sâu k-x-1 bên phải)
  67. # = 2^(x-1) * 2^(k-x-1) = 2^(k-2).
  68. # Điều kiện: x <= h và k-x <= h.
  69.  
  70. ways_via_root = 0
  71.  
  72. # Case đi thẳng 1 nhánh (x=0 hoặc x=k)
  73. if h >= k:
  74. ways_via_root += 2 * (2**(k-1)) # 2 nhánh, mỗi nhánh 2^(k-1) đích
  75.  
  76. # Case rẽ 2 nhánh (0 < x < k)
  77. # Cần đếm số lượng x sao cho: 1 <= x <= k-1 AND x <= h AND k-x <= h
  78. # Tức là: max(1, k-h) <= x <= min(k-1, h)
  79. low = max(1, k - h)
  80. high = min(k - 1, h)
  81.  
  82. if low <= high:
  83. count_valid_splits = high - low + 1
  84. ways_via_root += count_valid_splits * (2**(k-2))
  85.  
  86. cnt += ways_via_root
  87. perfect_memo[h] = cnt
  88. return cnt
  89.  
  90. # Hàm đếm số nút trong cây con gốc u ở độ sâu d (tương đối)
  91. def count_nodes_at_depth(u, d):
  92. if d < 0: return 0
  93. if d == 0: return 1
  94.  
  95. # Nút đầu tiên và cuối cùng ở độ sâu d trong cây con u
  96. # Chỉ số toàn cục: [u * 2^d, u * 2^d + 2^d - 1]
  97. # Cần dùng bit shift cẩn thận để tránh tạo số quá lớn không cần thiết,
  98. # nhưng Python xử lý BigInt tốt.
  99.  
  100. # Kiểm tra nhanh: nếu u quá lớn so với n thì 0
  101. # u * 2^d > n
  102. # Bit length check
  103. if u.bit_length() + d > n.bit_length() + 1: # ước lượng
  104. return 0
  105.  
  106. first = u << d
  107. if first > n:
  108. return 0
  109. last = first + (1 << d) - 1
  110.  
  111. if last <= n:
  112. return (1 << d)
  113. else:
  114. return max(0, n - first + 1)
  115.  
  116. total_paths = 0
  117.  
  118. # Hàm duyệt cây
  119. def traverse(u):
  120. nonlocal total_paths
  121. if u > n:
  122. return
  123.  
  124. # 1. Tính đóng góp của u với tư cách là LCA
  125. # Ta cần tính tổng: count(left, x-1) * count(right, k-x-1)
  126. # Tối ưu: count_nodes_at_depth thực ra tốn chi phí log.
  127. # Vòng lặp k lần. Tổng chi phí O(k * log n).
  128. # Với k lớn, ta có thể tối ưu hơn, nhưng thường k <= 60-100 trong các bài toán cây này.
  129. # Nếu k quá lớn (> 120), số đường đi là 0 (vì chiều cao cây ~ 60).
  130. if k > 130: # Chiều cao cây 10^18 < 60. Đường đi tối đa ~ 120.
  131. return
  132.  
  133. ways = 0
  134. # Case: Gốc -> Trái x, Phải k-x
  135. # x = 0: Gốc -> Phải k
  136. # x = k: Gốc -> Trái k
  137.  
  138. # Pre-calculate counts to avoid re-calling logic?
  139. # No, direct is fine.
  140.  
  141. # Loop x from 0 to k
  142. for x in range(k + 1):
  143. left_len = x
  144. right_len = k - x
  145.  
  146. c_left = 0
  147. c_right = 0
  148.  
  149. # Left branch contribution
  150. if left_len == 0:
  151. c_left = 1 # Đại diện chính nút u
  152. else:
  153. c_left = count_nodes_at_depth(2*u, left_len - 1)
  154.  
  155. if c_left == 0: continue
  156.  
  157. # Right branch contribution
  158. if right_len == 0:
  159. c_right = 1
  160. else:
  161. c_right = count_nodes_at_depth(2*u + 1, right_len - 1)
  162.  
  163. if c_right > 0:
  164. if left_len == 0 and right_len == 0:
  165. continue # Độ dài 0, không tính (hoặc tính là 0 đường)
  166.  
  167. # Lưu ý: nếu left_len > 0 và right_len > 0 thì đây là đường đi ghép
  168. # Nếu 1 trong 2 bằng 0 thì là đường đi thẳng.
  169. # Logic count_nodes đã đếm số nút đích. Mỗi nút đích ứng với 1 đường đi duy nhất từ u.
  170. # Nên ta nhân số lượng đích.
  171. ways += c_left * c_right
  172.  
  173. total_paths += ways
  174.  
  175. # 2. Kiểm tra xem cây con hiện tại có phải là cây hoàn hảo không để cắt tỉa
  176. # Kiểm tra cây hoàn hảo "đủ lớn" để chứa các đường đi còn lại
  177. # Thực ra chỉ cần kiểm tra: cây con u có phải là cây hoàn hảo chiều cao H nào đó không.
  178. # Cách kiểm tra:
  179. # Nút u có chiều cao H trong cây hoàn hảo nếu:
  180. # (u << H) + (1 << H) - 1 <= n (Nút phải cùng lớp H nằm trong n)
  181. # VÀ (u << (H+1)) > n (Lớp H+1 không có nút nào - tức là cây kết thúc chính xác tại H)
  182.  
  183. # Tìm chiều cao tối đa có thể của u
  184. # Max depth của toàn bộ cây ~ 60
  185. # Ta thử tìm H sao cho cây con u là cây hoàn hảo chiều cao H
  186.  
  187. # Ước lượng chiều cao từ u đến đáy:
  188. # bit_len(n) - bit_len(u)
  189.  
  190. h_est = n.bit_length() - u.bit_length()
  191.  
  192. # Kiểm tra h_est
  193. if h_est >= 0:
  194. # Kiểm tra xem có phải hoàn hảo chiều cao h_est không
  195. right_leaf = (u << h_est) + (1 << h_est) - 1
  196. next_left = u << (h_est + 1)
  197.  
  198. if right_leaf <= n and next_left > n:
  199. # Chính xác là cây hoàn hảo chiều cao h_est
  200. # Tuy nhiên, ta đã tính LCA tại u rồi.
  201. # Ta cần cộng số đường đi nằm TRỌN trong con trái và con phải.
  202. # get_perfect_paths(h_est) bao gồm cả đường đi qua LCA (gốc u).
  203. # NÊN: ta cộng get_perfect_paths(h_est) rồi TRỪ đi phần LCA đã tính?
  204. # Hay là return luôn?
  205. # get_perfect_paths tính TOÀN BỘ đường đi trong cây con.
  206. # Hàm traverse hiện tại đang tính LCA(u) rồi gọi đệ quy con.
  207. # Nếu ta return get_perfect_paths(h_est) thì ta phải KHÔNG tính LCA(u) ở trên, hoặc trừ đi.
  208. # Cách dễ nhất: Đừng tính LCA ở trên nếu phát hiện là cây hoàn hảo.
  209. # Nhưng code đã tính rồi.
  210. # Logic lại:
  211. # Check perfect trước. Nếu perfect -> return DP.
  212. # Nếu không -> Tính LCA, recurse.
  213. pass
  214.  
  215. # Viết lại hàm traverse gọn hơn với logic check trước
  216. def traverse_optimized(u):
  217. nonlocal total_paths
  218. if u > n: return
  219.  
  220. # Check perfect tree
  221. h_est = n.bit_length() - u.bit_length()
  222. is_perfect = False
  223. if h_est >= 0:
  224. right_leaf = (u << h_est) + (1 << h_est) - 1
  225. next_left = u << (h_est + 1)
  226. if right_leaf <= n and next_left > n:
  227. total_paths += get_perfect_paths(h_est)
  228. return
  229.  
  230. # Nếu không perfect (hoặc là perfect nhưng bị cắt cụt dưới), tính thủ công
  231. # 1. LCA contribution
  232. ways = 0
  233. if k <= 130:
  234. for x in range(k + 1): # x là số cạnh bên trái
  235. # Nếu x=0: đi thẳng phải k cạnh.
  236. # Nếu x=k: đi thẳng trái k cạnh.
  237. # Nếu 0<x<k: trái x, phải k-x.
  238.  
  239. # Số cạnh bên trái là x => cần nút ở độ sâu x (tương đối u) ?
  240. # Không, nút ở độ sâu x tương đối u là ĐẦU MÚT.
  241. # Đường đi từ u đến nút độ sâu x có độ dài x.
  242. # Vậy ta cần tìm số nút ở độ sâu x bên trái (tức là độ sâu x-1 tính từ con trái 2u).
  243.  
  244. count_L = 0
  245. count_R = 0
  246.  
  247. if x == 0:
  248. count_L = 1 # u
  249. else:
  250. count_L = count_nodes_at_depth(2*u, x - 1)
  251.  
  252. if count_L == 0: continue
  253.  
  254. if k - x == 0:
  255. count_R = 1 # u
  256. else:
  257. count_R = count_nodes_at_depth(2*u + 1, (k - x) - 1)
  258.  
  259. if count_R > 0:
  260. # Nếu cả 2 đều là u (k=0), ways += 1.
  261. # Nhưng loop chạy 1 lần x=0. countL=1, countR=1 -> ways+=1. Đúng.
  262. # Nếu k > 0.
  263. # x=0: L=1, R=cnt(right, k-1). ways += cnt. Đúng (đường đi thẳng phải).
  264. # x=k: L=cnt(left, k-1), R=1. ways += cnt. Đúng (đường đi thẳng trái).
  265. # 0<x<k: ways += L * R. Đúng.
  266. ways += count_L * count_R
  267.  
  268. # Trừ đi trường hợp x=0 và x=k đếm trùng u?
  269. # Không. x=0 nghĩa là đường đi nằm hẳn bên phải u (bắt đầu từ u).
  270. # x=k nghĩa là đường đi nằm hẳn bên trái u.
  271. # Chúng là các tập đường đi rời nhau.
  272.  
  273. # Tuy nhiên, nếu k=0. Loop x=0. L=1, R=1. ways=1.
  274. # Nhưng ở đầu ta đã handle k=0 -> n.
  275. # Với k > 0, x=0 và x=k là các đường đi khác nhau.
  276. # Nhưng lưu ý: Logic trên tính số cặp (u, v) hay số đường đi?
  277. # Đường đi vô hướng.
  278. # Cách tính trên là "đếm số đường đi có đỉnh cao nhất là u".
  279. # Với x=0: Đường u -> ... -> v (bên phải). LCA là u.
  280. # Với x=k: Đường u -> ... -> v (bên trái). LCA là u.
  281. # Với 0<x<k: v1 <- ... <- u -> ... -> v2. LCA là u.
  282. # Tất cả đều có LCA là u duy nhất. Không bị trùng.
  283. pass
  284.  
  285. total_paths += ways
  286.  
  287. # 2. Recurse
  288. traverse_optimized(2*u)
  289. traverse_optimized(2*u + 1)
  290.  
  291. traverse_optimized(1)
  292. print(total_paths)
  293.  
  294. if __name__ == '__main__':
  295. solve()
Success #stdin #stdout 0.1s 14060KB
stdin
Standard input is empty
stdout
Standard output is empty