C [yLOI2019] 棠梨煎雪
Background
歲歲花藻檐下共將棠梨煎雪
自總角至你我某日輾轉天邊
天淡天青 宿雨沾襟
一年一會信箋卻只見寥寥數言
——銀臨《棠梨煎雪》
Description
給定 \(m\) 個長度爲 \(n\) 的可能含有 ?
的 01 串,其中 ?
既能代表 0
也能代表 1
, \(q\) 次操作,每次給定一個區間,求有多少 01 串滿足區間內的所有字符串都可以解釋成該 01 串,或者單點修改某個字符串。
Limitations
Solution
子任務 \(1\):
輸出 \(0\) 即可得分,期望得分 \(5~pts\)。
子任務 \(2\):
考慮 \(n\) 只有 \(10\),因此可以 \(O(2^n)\) 去枚舉所有可能的串,然後對於每個詢問 \(O(m)\) 的逐個判定是否合法。時間複雜度 \(O(qm2^n)\),期望得分 \(10~pts\)。
子任務 \(3\):
考慮對於一段所有字符串的第 \(x\) 個字符,一共有四種可能:確定爲 \(0\);確定爲 \(1\);都可以;都不可以。如果 \(0/1\) 都不可以,則答案爲 \(0\),因爲不會有任何一個字符串匹配該區間。如果確定爲某個數,則這一位只有一種可能;否則這一位有兩種可能。根據乘法原理,如果有 \(a\) 個位置有兩種可能,則本次詢問的答案爲 \(2^a\)。
因此對於每個詢問,\(O(nm)\) 地去遍歷區間內所有字符即可。時間複雜度 \(O(nmq)\),期望得分 \(15~pts\)。
子任務 \(4\):
考慮 \(n\) 只有 \(30\),可以狀壓到 int
中。具體的,維護兩個 int
,第一個 int
維護對應位是否確定是 \(0\) 或 \(1\),第二個 int
維護如果確定是 0
或 1
了那麼具體是 0
還是 1
。
例如,對於單個字符串,它所有的爲 ?
的位置,在第一個 int
中對應位置是 0
,所有爲 0
或 1
的位置,在第在個 int
中對應的位置是 1
,在第二個 int
中對應的位置是自身的值。
考慮 \(a_1,~a_2\) 是詢問的左端點到某個字符串之前所維護的兩個 int
,\(b_1,~b_2\) 是該字符串的兩個 int
,現在合併這兩個信息。
如果某一位置即不可以是 \(1\),也不可以是 \(0\),那麼該字符串不爲 ?
的位置在 \(b_2\) 中對應的值應該至少有一個和 \(a_2\) 中對應位置的值且 \(a_1\) 的該位置爲 \(1\),位運算可以表現爲 \((a1~\&~b_1)~\&~(a_2~\oplus~b_2) ~\neq 0\),則該詢問的答案爲 \(0\)。
否則這兩段信息可以合併:將他們已經確定字符的位置合併起來,然後將確定位置對應的值合併起來即可。於是 \(a_1\) 對 \(b_1\) 取或, \(a_2\) 對 \(b_2\) 取或即可。
最終該詢問 \(0/1\) 都可以的位置的個數即爲 \(a_1\) 中 \(1\) 的個數。
時間複雜度 \(O(mq)\),期望得分 \(15~pts\)
子任務 \(5\):
由於 \(n\) 只有 \(1\),問題變成了求某個區間內的字符是不是全是 0
,全是 1
,全是 ?
或 0
和 1
都有。可以考慮用線段樹非常輕鬆的維護這樣的信息。
時間複雜度 \(O(q \log m)\),期望得分 \(15~pts\)
子任務 \(6\):
世界上沒有什麼事情是開一棵線段樹不能解決的,如果有,那就開 \(30\) 棵。
時間複雜度 \(O(nq \log m)\),期望得分 \(10~pts\)
子任務 \(7\):
考慮結合子任務 \(4\) 和子任務 \(5\) 的做法,發現兩個區間的狀壓信息也可以用子任務 \(4\) 的方法合併。因此用線段樹維護這兩個 int
的狀壓信息即可。
時間複雜度 \(O(q \log m)\),期望得分 \(30~pts\)