Luogu 🟡 P14359 [CSP-J 2025] 异或和
🔗 🟡 P14359 [CSP-J 2025] 异或和
Problem Statement
題目簡述
給定長度為 的非負整數序列與目標值 。需要選出盡可能多個互不相交的非空連續區間,使得每個區間內所有元素的按位異或和都等於 。
請輸出最多能選出的區間數量。
Constraints
約束條件
Example
Input 1
1 | 4 2 |
Output 1
1 | 2 |
可以選 和 ,兩段的異或和分別是 和 。
Input 2
1 | 4 0 |
Output 2
1 | 1 |
雖然 與 的異或和都為 ,但它們相交,所以不能同時選。
思路:前綴異或 + 枚舉右維護左 + 貪心
設前綴異或和 為:
則區間 的異或和為:
我們希望它等於 ,所以:
等價於:
也就是固定 的右端點 ,只要找到某個左端點 ,使得前綴異或和 ,就能形成一段合法區間。
當右端點固定後,合法左端點的前一個位置必須對應到某個指定的前綴值。因此只要記錄每種前綴異或值最後一次出現的位置,就能 判斷目前是否能形成一段合法區間。
貪心,找到就立刻切
答案是要。
想讓段數最多,應該優先選右端點最早的合法區間。因為越早結束,留給後面的空間越大,不會讓後續選擇變差。
更具體地說,當掃描到某個位置時,這是目前能選到的最早結束合法區間。如果不選它,改等後面才切,前面空出來的部分也不能和後面的區間重疊使用,反而只會讓下一段的起點更晚或不變,不可能得到更多段。
正確性說明:交換論證
假設某個最優方案在目前已經存在合法區間時,沒有選這個最早結束的區間,而是選了之後才結束的第一段。把那一段替換成目前這段,段數不變,且第一段結束位置更早,後面的可用範圍只會變大。因此存在一個最優方案會選目前這段。於是掃描時一旦能切,就立刻切是安全的。
如何避免區間相交
用 last 記錄上一段已選區間的右邊界。當目前查到的前綴位置不在 last 之後,代表形成的區間會和上一段相交,不能選;只有左端點落在 last 之後,才是一段新的合法區間。
此外,對於固定的右端點來說,我們希望合法的左端點盡量靠右,這樣形成的區間越短,越容易避開上一段已選區間。因此只需要保留每個前綴異或值最後出現的位置即可。
先用前綴異或把區間條件轉成單點查詢,再用最早結束優先的貪心處理互不相交限制。
複雜度分析
- 時間複雜度:
- 空間複雜度:
Code
1 | from collections import defaultdict |
寫在最後
The cover image was created by @4AUB. All rights belong to the original artist.
It is used here only as a non-commercial cover illustration for this note. I do not claim ownership of the artwork.
If you are the copyright holder and believe this usage is inappropriate, please contact me by email or leave a comment. I will remove the image promptly.




![Luogu 🟡 P14359 [CSP-J 2025] 异或和](https://i.pixiv.cat/img-master/img/2026/06/21/14/33/23/146273507_p0_master1200.jpg)

