首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

POJ 3225 區間操作:線段樹維護區間覆蓋與異或

     編輯:C++ 入門

問題轉化

對區間進行交(U)、並(I)、差(D)、補(C)、對稱差(S)五種操作,最終輸出結果集合。
關鍵技巧:將座標擴大 2 倍,偶數點代表端點,奇數點代表區間內部。開區間端點向內縮 1,閉區間保持。例如 [1,3] → [2,6],(1,3) → [3,5]。

操作映射為區間覆蓋/翻轉

  • U T:[a,b] 覆蓋 1
  • I T:[0,a-1] 和 [b+1,MAX] 覆蓋 0
  • D T:[a,b] 覆蓋 0
  • C T:[0,a-1] 和 [b+1,MAX] 覆蓋 0,[a,b] 翻轉
  • S T:[a,b] 翻轉

線段樹懶標記設計

每節點維護:

  • col:-1 表示無整體覆蓋,0/1 表示整段被覆蓋為 0/1
  • rev:0/1 表示整段是否需異或(僅當 col=-1 時有效)

下推邏輯:

  • 若父節點 col != -1:子節點 col 同步,rev 清 0
  • 若父節點 rev == 1:子節點若有 col 則翻轉 col,否則翻轉 rev

最終查詢

遍歷線段樹收集所有值為 1 的葉子區間,根據奇偶還原原始座標的開閉,合併相鄰區間輸出。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved