programming.in.th · ข้อ 2042
ระบาย 0 หรือ 1 ให้ทุกเส้นบนต้นไม้ โดยทุกคู่บรรพบุรุษกับลูกหลานที่โจทย์ระบุ ต้องมีเส้น 1 คั่นอย่างน้อยหนึ่งเส้น นับวิธีทั้งหมดมอด 998244353 สถานะที่ใช้คือความลึกของข้อบังคับที่ยังค้างอยู่ลึกที่สุด และการรวมลูกเข้าด้วยกันทำด้วยการควบรวมเซกเมนต์ทรี
โจทย์เล่าว่าโชคชะตาของคนหนึ่งคนคือต้นไม้ที่ปักรากไว้ที่จุด 1 รากคือการเกิด ใบคือการตาย การเดินจากจุดหนึ่งลงไปหาอีกจุดคือช่วงชีวิตช่วงหนึ่ง
คู่ (u, v) ที่ u เป็นบรรพบุรุษ (ancestor อ่านว่า "แอนเซสเตอร์" แปลว่าผู้ที่มาก่อน)
ของ v คือจุดที่อยู่เหนือ v บนทางขึ้นไปหาราก วิถีจาก u ลงไป v ก็คือประสบการณ์หนึ่งช่วงของชีวิต
เราระบายเส้นเชื่อมทุกเส้นด้วยเลข 0 หรือ 1 เส้นที่ได้ 1 เรียกว่าเส้นสำคัญ เงื่อนไขมีข้อเดียว: วิถีของทุกคู่ที่โจทย์ระบุต้องมีเส้นสำคัญอย่างน้อยหนึ่งเส้น
คำถามคือระบายได้ทั้งหมดกี่แบบ คู่ซ้ำกันได้ และคำตอบใหญ่มากจนต้องตอบเป็นเศษจากการหารด้วย 998,244,353
อินพุต / ขอบเขต / เอาต์พุต
N จำนวนจุดยอด ต่อด้วย N - 1 บรรทัด
แต่ละบรรทัดคือ x กับ y แทนเส้นเชื่อมระหว่างสองจุดนั้น (ไม่บอกทิศทาง)
บรรทัดถัดมาคือ M แล้วปิดด้วย M บรรทัด แต่ละบรรทัดคือคู่ u กับ v u ≠ v โดย u
เป็นบรรพบุรุษของ v จริง คู่เดิมโผล่ซ้ำได้
1 ≤ N ≤ 500,000, 1 ≤ M ≤ 500,000,
เวลา 2 วินาที หน่วยความจำ 512 เมกะไบต์ N, M ≤ 10 (16%), N ≤ 2 000 (8%),
ต้นไม้ไบนารีสมบูรณ์ที่ N, M ≤ 10^5 (8%) และชุดสุดท้ายที่ไม่มีเงื่อนไขเพิ่ม (12%)
| Input | Output |
|---|---|
| 5 1 2 2 3 3 4 3 5 2 1 3 2 5 | 10 |
โจทย์มีตัวอย่างที่สองด้วย ต้นไม้ 15 จุดกับ 6 คู่ คำตอบคือ 960 หน้านี้ใช้มันเป็นด่านตรวจตอนบิลด์อีกชุด
อ่านตัวอย่างนี้ยังไง
เอาต์พุตคือจำนวนแบบของการระบาย หารด้วย 998,244,353 แล้วเอาเศษ ไม่ใช่จำนวนเส้นสำคัญที่น้อยที่สุด (ซึ่งในตัวอย่างนี้คือ 1 เส้น) ต้นไม้นี้มี 4 เส้น จึงมีการระบายทั้งหมด 16 แบบก่อนเอาเงื่อนไขมากรอง
วิถีของคู่ (1, 3) คือเส้น 1-2 กับ 2-3 ส่วนคู่ (2, 5) คือเส้น 2-3 กับ 3-5 เส้น 2-3 อยู่บนวิถีของทั้งสองคู่ จึงแบ่งคำตอบเป็นสองกอง
รวม 8 + 2 = 10 ตรงกับเอาต์พุต
ใบ้
นับตรง ๆ ไม่ไหวตั้งแต่แรก การระบายมี 2 ยกกำลัง 499,999 แบบ ทางที่เหลือคือไล่ต้นไม้จากใบขึ้นไปหาราก แล้วสรุปทุกอย่างข้างล่างให้เป็นของชิ้นเล็ก ๆ ชิ้นเดียว
ลองยืนที่จุดหนึ่งแล้วถามว่า ของที่ต้องหอบขึ้นไปให้พ่อคืออะไร ข้อบังคับที่วิถีอยู่ในกิ่งนี้ทั้งเส้นจัดการเสร็จแล้ว ไม่ต้องหอบ
ที่ต้องหอบคือข้อค้าง: ข้อที่ปลายล่างอยู่ในกิ่งนี้ ปลายบนอยู่เหนือขึ้นไป และบนทางจากปลายล่างขึ้นมาถึงจุดนี้ ยังไม่มีเส้นไหนเป็น 1 ทุกข้อค้างพูดเรื่องเดียวกัน: "ต้องมีเส้นสำคัญโผล่ก่อนไต่พ้นความลึกของ u"
ถ้ามีข้อค้างหลายข้อพร้อมกัน ต้องจำทุกข้อจริงหรือเปล่า
ลองหาคำตอบด้วยมือก่อน เกมแรกให้ระบายเองบนต้นไม้เล็ก ๆ เกมที่สองตอบคำถามที่ใบ้เพิ่งทิ้งไว้
ต้นไม้เดียวกับตัวอย่างข้างบน ลองระบายให้ผ่านทั้งสองคู่ดูก่อน แล้วดูว่าการ์ดบอกจำนวนแบบทั้งหมดว่าเท่าไร
แตะที่ป้ายบนเส้นเพื่อสลับระหว่าง 0 กับ 1
พอหาแบบที่ผ่านได้แล้ว การ์ดจะบอกว่าต้นไม้นั้นมีทั้งหมดกี่แบบ
ชิปใต้กระดานคือคู่ที่โจทย์สั่งไว้ คู่ที่ยังไม่ผ่านจะมีวิถีของมันเน้นสีแดงบนกระดาน
เกมที่สอง: ถ้ามีข้อค้างหลายข้อพร้อมกัน ขอบเส้นไหนปิดได้ครบทุกข้อ
โซ่ 6 จุด v อยู่ลึกสุด มีข้อบังคับค้าง 3 ข้อ ลองระบายขอบเป็น 1 ทีละเส้น แล้วดูว่าปิดได้กี่ข้อ
ยังไม่ได้ระบายขอบไหน ทั้ง 3 ข้อยังค้าง
ลองแล้ว 0 จาก 5 ขอบ
ลองให้ครบทั้งสองเกมก่อนนะครับ โดยเฉพาะต้นที่สองกับต้นที่สามในเกมแรก และผลของเกมที่สอง เพราะเฉลยข้างล่างจะพูดถึงมัน
ไล่จากช้าไปเร็ว มีสามขั้น ทุกขั้นตอบถูกเหมือนกัน ต่างกันแค่ว่ารอดต้นไม้แบบไหน
ขั้นที่สองกับสามใช้ dp (ย่อจาก dynamic programming อ่านว่า "ไดนามิก โปรแกรมมิง") คือแก้ปัญหาใหญ่จากคำตอบของปัญหาย่อยที่เก็บไว้ ที่นี่ปัญหาย่อยคือ "กิ่ง" ของแต่ละจุด หมายถึงจุดนั้นกับทุกจุดที่อยู่ใต้มัน
วิธีที่ 1
2N − 1 แบบ × เดินทุกคู่
ลองทุกแบบแล้วเช็กทุกคู่ตามนิยามตรง ๆ หน้านี้ใช้มันเป็นตัวตรวจคำตอบด้วย
ได้ชุด N, M ≤ 10 (16%)
วิธีที่ 2
ผลรวมความลึกของทุกจุด
แต่ละจุดถือตารางยาวเท่าความลึกของมัน งานรวมจึงเท่ากับผลรวมความลึก ซึ่งบนเส้นตรงเป็นราว N² ÷ 2 (ตอนที่ 2 และ 3 เล่าสถานะกับสูตร)
ได้ชุด N ≤ 2,000 และชุดไบนารีสมบูรณ์
วิธีเต็ม
ราว N log N + M
สูตรเดียวกับวิธีที่ 2 แต่เก็บตารางในเซกเมนต์ทรี (ต้นไม้ที่แต่ละปมเก็บผลรวมของช่วง) แบบที่ช่องว่างไม่กินเวลา เล่าในตอนที่ 4
ได้ครบทุกชุด
วิธีที่ 1 ตายเร็วมาก ต้นไม้ 30 จุดก็มีการระบายเกินห้าร้อยล้านแบบแล้ว ส่วนวิธีที่ 2 ตายเฉพาะต้นไม้ลึก เพราะจุดที่ลึก d ถือตารางยาว d ช่อง
ตารางเต็มบนเส้นตรงแค่ 100,000 จุด วัดได้จริง 60.23 วินาที ทั้งที่ขอบเขตจริงยาวกว่านั้นห้าเท่า และเวลาโตเป็นกำลังสอง
สิ่งที่ทั้งวิธีที่ 2 และวิธีเต็มใช้ร่วมกันคือสถานะของ dp ซึ่งเป็นแก่นของข้อนี้ เริ่มจากตรงนั้นก่อน
เกมที่สองเมื่อกี้ให้ผลว่า ขอบใดก็ได้ที่อยู่ระหว่าง u ที่ลึกที่สุดกับ v ปิดได้ครบทุกข้อ ส่วนขอบที่สูงกว่านั้นปิดได้ไม่ครบ ตอนนี้มาดูว่าข้อสังเกตนี้กลายเป็นสถานะของ dp ได้ยังไง
ที่มาของแนวคิดนี้
ผมรู้ตั้งแต่อ่านโจทย์จบว่านี่เป็น dp บนต้นไม้ สิ่งที่ยังไม่รู้คือสถานะต้องเป็นอะไร
แรงกดดันมาจากการนับ ถ้าเก็บว่า "ข้อไหนยังค้างอยู่บ้าง" เป็นเซต จุดหนึ่งอาจมีข้อค้างเป็นแสนข้อ สถานะจึงต้องยุบเซตนั้นให้เหลือตัวเลขตัวเดียว
พอวาดโซ่ดูก็เห็นว่าข้อที่ u ลึกกว่าเข้มกว่าเสมอ เพราะทางที่เหลือให้มันปิดสั้นกว่า บทเรียนที่เอาไปใช้ข้ออื่นได้: เวลาสถานะอยากเป็นเซต ให้ถามก่อนว่าของในเซตเทียบความเข้มงวดกันได้ไหม
นึกภาพ
ข้อค้างแต่ละข้อเหมือนพัสดุที่ต้องส่งก่อนเส้นตายของตัวเอง ระหว่างไต่ขึ้นหาราก เราเจอเส้นตายของ u ที่ลึกที่สุดก่อนเสมอ
ส่งทันเส้นตายที่ใกล้ที่สุดได้เมื่อไร ชิ้นที่เส้นตายไกลกว่าก็ทันไปด้วย จึงจำแค่เส้นตายที่ใกล้ที่สุดก็พอ
สถานะที่ใช้ทั้งหน้า
ให้ความลึกของรากเป็น 1 แล้ว dp[v][j] = จำนวนวิธีระบายเส้นในกิ่งของ v ที่
j พอดี ข้อค้าง คือข้อ (u, x) ที่ x อยู่ในกิ่งนี้ u อยู่เหนือ v ขึ้นไป
และบนทางจาก x ขึ้นมาถึง v ยังไม่มีเส้นไหนเป็น 1 j เรียกว่าระดับค้าง ส่วน j = 0 คือไม่มีอะไรค้าง
ระดับค้างอยู่ในช่วง 0 ถึง ความลึกของ v ลบหนึ่ง เพราะ u อยู่เหนือ v เสมอ
ต้นที่สองในเกมแรกเป็นตัวอย่างพอดี คู่ (1, 4) กับคู่ (2, 4) จบที่จุดเดียวกัน วิถีของคู่หลังสั้นกว่าและซ้อนอยู่ในวิถีของคู่แรก ปิดคู่หลังได้เมื่อไรคู่แรกก็ปิดตาม
โค้ดทำสิ่งนี้ด้วยบรรทัดเดียว คือเก็บ att[v] (ย่อจาก attach แปลว่าแขวน) เป็นค่ามากสุดของความลึกของ u
ทุกตัวที่จบที่ v คู่ซ้ำจึงไม่ต้องนับสองรอบไปด้วยเลย
พอสถานะเป็นเลขตัวเดียว การเดินขึ้นก็เหลือสามเรื่อง: ส่งตารางผ่านขอบขึ้นไปหาพ่อ รวมหลายกิ่งเข้าด้วยกัน และแขวนข้อบังคับที่จบที่จุดนั้น
ขอบที่ต่อจุด c กับพ่อ ให้ D เป็นความลึกของพ่อ
ตารางที่ c ส่งขึ้นไปคือ g มีช่อง 0 ถึง D − 1 และ S คือผลรวมทั้งตารางของลูก
อ่านสูตรนี้แบบยืนที่ช่องปลายทางแล้วถามว่ามีอะไรไหลเข้ามาบ้าง ดัชนีในตารางเป็นความลึก จึงไม่ขยับตอนเราไต่ขึ้นหนึ่งขั้น สิ่งที่เปลี่ยนคือช่วงที่ยังใช้ได้หดลงหนึ่งช่อง
0 รับ S มาจากการระบายขอบนี้เป็น 1 ข้อค้างทุกข้อที่หอบขึ้นมา
ถูกปิดตรงนี้พร้อมกันหมด ไม่ว่าก่อนหน้านี้จะค้างอยู่ระดับไหน ตารางทั้งตารางจึงยุบมาลงช่องเดียว
0 รับ dp[c][0] เพิ่มอีกทาง จากการระบายเป็น 0 ตอนที่ไม่มีอะไรค้างอยู่แล้ว
ไม่มีอะไรให้หอบ มันก็ยังไม่มีอะไรให้หอบต่อ
j ตั้งแต่ 1 ถึง D - 1 รับ dp[c][j] ตรง ๆ จากการระบายเป็น 0
ทั้งที่ยังค้างอยู่ที่ระดับ j เส้นตายไม่เลื่อน เพราะมันผูกกับความลึกของ u
แค่เสียโอกาสไปหนึ่งเส้น
dp[c][D] ไม่ไหลไปไหนเลยในทางระบาย 0 เพราะ D คือความลึกของพ่อ
แปลว่าข้อค้างนั้นมี u เป็นพ่อของ c พอดี ขอบนี้คือเส้นสุดท้ายบนวิถีของมัน
ระบาย 0 คือยอมแพ้ (ส่วนทางระบาย 1 นับมันไปแล้วใน S)
แต่ละกิ่งหอบระดับค้างของตัวเองขึ้นมา แต่ถนนข้างบนมีสายเดียว ระดับค้างหลังรวมจึงเป็นค่ามากสุดของระดับค้างทั้งสองฝั่ง (มากสุดของระดับ ส่วนตัวเลขในตารางเอามาคูณกัน เพราะแต่ละฝั่งเลือกได้อิสระ)
ให้ A กับ B เป็นสองตาราง preA, preB เป็นผลรวมสะสม และถือว่า preA[−1] = 0
จุดที่ยังไม่มีลูกเริ่มจากตาราง [1, 0, 0, …] ซึ่งรวมกับอะไรก็ได้ของเดิม
A ค้างอยู่ที่ j พอดี ส่วน B ค้างที่ไหนก็ได้
ที่ไม่เกิน j ค่ามากสุดจึงเป็น j B ค้างอยู่ที่ j พอดี ส่วน A ค้าง
น้อยกว่า j จริง ๆ ที่ต้องเป็น "น้อยกว่า" ไม่ใช่ "ไม่เกิน"
ก็เพราะกรณีที่ทั้งคู่เท่ากับ j ถูกนับไปแล้วในพจน์แรก นับซ้ำเมื่อไรคำตอบพัง
ทำหลังรวมลูกครบแล้ว ให้ b = att[v]
ทุกช่องที่ j น้อยกว่า b ถูกกวาดมาเทลงช่อง b เพราะเงื่อนไขใหม่เข้มกว่าของเดิม
ช่องที่ j ไม่น้อยกว่า b ไม่ต้องแตะ เพราะของเดิมเข้มกว่าอยู่แล้ว
ลองเดินดูกับตัวอย่างที่หนึ่ง จุดสีทองบนต้นไม้คือจุดที่กำลังคำนวณ ข้อความใต้กระดานแสดงตารางระหว่างทางทุกจังหวะ
ตาราง dp ของตัวอย่างที่หนึ่ง จากใบขึ้นไปหาราก
| จุด | ลึก | att | j = 0 | j = 1 | j = 2 | j = 3 |
|---|---|---|---|---|---|---|
| 5 | 4 | 2 | 0 | 0 | 1 | 0 |
| 4 | 4 | · | 1 | 0 | 0 | 0 |
| 3 | 3 | 1 | 0 | 2 | 2 | · |
| 2 | 2 | · | 4 | 2 | · | · |
| 1 | 1 | · | 10 | · | · | · |
"·" คือช่องที่ไม่มีอยู่ เพราะระดับค้างต้องตื้นกว่าตัวจุดเอง
สองจังหวะที่ของหายจริงอยู่ตอนไต่ขึ้น จากจุด 3 ขึ้นไปจุด 2 ช่อง 2 ของจุด 3 (ค่า 2) หายในทางระบาย 0 เพราะ u ของมันคือจุด 2 พอดี และจากจุด 2 ขึ้นไปราก ช่อง 1 (ค่า 2) ก็หายด้วยเหตุผลเดียวกัน
อ่านคำตอบจากแถวของจุด 2
ทางระบายขอบ 1-2 เป็น 1 = ผลรวมทั้งแถว = 6
ทางระบายเป็น 0 ที่ไม่มีอะไรค้าง = ช่อง 0 = 4
รวม 6 + 4 = 10 ตรงกับเอาต์พุต
สูตรของตอนที่ 3 ถูกแล้ว ปัญหาคือเวลา บนต้นไม้เส้นตรง 500,000 จุด ผลรวมความลึกคือราว 125,000,000,000 ช่อง ซึ่งต้องแตะทีละช่อง (ส่วนหน่วยความจำไม่ใช่ปัญหา เพราะตารางถูกทิ้งทันทีที่ส่งขึ้นไป)
แต่ตารางพวกนี้ว่างเกือบหมด ช่อง j ≥ 1 ที่มีค่าไม่เป็นศูนย์เกิดจากการแขวนเท่านั้น ซึ่งเกิดได้แค่ครั้งเดียวต่อจุด ที่เก็บที่ดีจึงต้องไม่เสียที่และไม่เสียเวลากับช่องว่าง
การรวมสองตารางทำด้วยการควบรวม (merging อ่านว่า "เมิร์จจิ้ง" แปลว่าควบรวม) คือเดินสองต้นลงไปพร้อมกัน แล้วยุบเหลือต้นเดียว ตรงที่ทั้งสองต้นมีปม เดินลงต่อ ตรงที่ต้นหนึ่งว่าง ทำงานจบในขั้นเดียว
ทำไมฝั่งว่างจบในขั้นเดียว
ถ้า B ว่างทั้งช่วง [l, r] แปลว่า B[j] = 0 และ preB[j]
เท่ากับผลรวมของ B ก่อน l ทุกช่อง สูตรรวมเหลือ C[j] = A[j] × ค่าคงที่
ค่าคงที่นี้รู้ได้ระหว่างเดิน เพราะการควบรวมพกผลรวมสะสมของทั้งสองฝั่งไปจากซ้ายไปขวา (รวมช่อง 0 ที่อยู่นอกต้นไม้ด้วย) ก่อนลงลูกขวาก็บวกผลรวมของลูกซ้ายเข้าไป
นั่นคือการคูณทั้งช่วงด้วยเลขตัวเดียว ซึ่งป้ายคูณทำได้ที่ปมเดียว ฝั่ง A ว่างก็เหมือนกัน แค่สลับบทบาท
อีกสองงานของตอนที่ 3 ทำบนต้นไม้แบบนี้
เวลาทั้งหมดคุมด้วยจำนวนปมที่เคยถูกสร้าง ทุกชั้นที่การควบรวมเดินลง ปมของต้น B หายไปหนึ่งปม ปมหายได้ไม่เกินจำนวนที่เคยสร้าง
ปมใหม่เกิดเฉพาะตอนแขวน ครั้งละไม่เกินราว log N ปม และไม่เกินหนึ่งครั้งต่อจุด
รวมแล้วเป็นราว O(N log N + M) โดย M มาจากการอ่านคู่ ซึ่งยุบเหลือ att ต่อจุดตั้งแต่อ่าน
รายละเอียดที่โค้ดเต็มทำต่างจากสูตรมีสองที่
j = 0 เป็นตัวแปรธรรมดาชื่อ s[v] ไม่อยู่ในต้นไม้ เพราะทางระบาย 1 เทของลงช่องนี้ทุกขอบ ถ้าอยู่ในต้นไม้ทุกขอบจะต้องสร้างปมใหม่freeList) แล้วเอามาใช้ซ้ำโค้ดเต็มแบ่งเป็นห้าช่วง แต่ละช่วงมีคอมเมนต์หัวเป็นชื่อเดียวกับคอลัมน์แรก อ่านคู่กับเฉลยตอนที่ระบุได้เลย
| ช่วงในโค้ด | ทำอะไร | อ่านคู่กับ |
|---|---|---|
| อ่านอินพุต | อ่านทั้งก้อนแล้วแกะตัวเลขเอง อินพุตใหญ่ราว 13 เมกะไบต์ | ตารางเวลา |
| เซกเมนต์ทรีที่ควบรวมได้ | บวกช่องเดียว ตัดช่วงทิ้ง และควบรวมสองต้นพร้อมป้ายคูณ | ตอนที่ 4 |
| ปักรากที่ 1 หาความลึกกับลำดับ | ใช้ BFS (ค้นตามแนวกว้าง) เพราะต้นไม้ลึกได้ห้าแสน การเรียกตัวเองซ้ำจะทำสแต็กล้น ลำดับย้อนกลับคือจากใบขึ้นราก | ตอนที่ 3 |
| ข้อบังคับ: เก็บแค่ u ที่ลึกที่สุดต่อจุดปลาย | att[v] = ค่ามากสุด คู่ซ้ำหายไปเองตรงนี้ | ตอนที่ 2 |
| ไล่จากใบขึ้นหาราก | แขวน ส่งผ่านขอบ แล้วรวมเข้าตารางของพ่อ | ตอนที่ 3 |
| ชุดทดสอบ | โปรแกรม | เวลา | หน่วยความจำสูงสุด |
|---|---|---|---|
| ต้นไม้สุ่ม | โค้ดเต็ม | 0.61 วินาที | 63 เมกะไบต์ |
| เส้นตรง (ลึก 500,000) | โค้ดเต็ม | 0.86 วินาที | 116 เมกะไบต์ |
| ดาว (ลึก 2) | โค้ดเต็ม | 0.34 วินาที | 53 เมกะไบต์ |
| ไบนารีสมบูรณ์ | โค้ดเต็ม | 0.60 วินาที | 70 เมกะไบต์ |
| ไม้กวาด (ก้านยาวครึ่งหนึ่ง) | โค้ดเต็ม | 0.88 วินาที | 90 เมกะไบต์ |
| พุ่มลึก (พ่อห่างขึ้นไป 1 ถึง 5) | โค้ดเต็ม | 1.10 วินาที | 109 เมกะไบต์ |
| เส้นตรง N = M = 100,000 | ตารางเต็ม | 60.23 วินาที | 14 เมกะไบต์ |
| เส้นตรง N = M = 100,000 | โค้ดเต็ม | 0.13 วินาที | 23 เมกะไบต์ |
| ไบนารีสมบูรณ์ N = M = 100,000 | ตารางเต็ม | 0.19 วินาที | 25 เมกะไบต์ |
ทั้งหมดนี้ตรวจกับตัวตรวจของผมเองกับตัวอย่างในโจทย์ ยังไม่ได้ส่งเข้าเครื่องตรวจจริง
สามข้อนี้ตอบได้จากสิ่งที่อ่านมา ลองคิดก่อนแล้วค่อยเปิดคำตอบ
ข้อ 1. ถ้าคู่เดิมโผล่ซ้ำสิบครั้ง โค้ดต้องทำอะไรเพิ่มไหม
ข้อ 2. ตอนส่งตารางจากจุด c ขึ้นไปหาพ่อ ทำไมช่อง D (ความลึกของพ่อ) ถึงหายไปในทางระบาย 0
ข้อ 3. ทำไมตารางเต็มเร็วบนต้นไม้ไบนารีสมบูรณ์ แต่ช้ามากบนเส้นตรง ทั้งที่ N เท่ากัน
จำแค่ข้อบังคับที่ค้างอยู่ลึกที่สุด ส่งผ่านขอบด้วยสองทางเลือก รวมกิ่งด้วยค่ามากสุด แล้วเก็บตารางเป็นเซกเมนต์ทรีที่ควบรวมได้เพื่อรอดต้นไม้ลึก
ในหน้านี้