[68] (NOIP集訓) NOIP2024 加賽 5

HaneDaniko發表於2024-11-20

恐將成為我改題時間最長的一場(也是分最低的一場)

碼長斷崖式領先了

flowchart TB A(暴力操作) style A color:#ffffff,fill:#00c0c0,stroke:#ffffff

首先你肯定要讓小於(等於)中位數的數變小,將較大的值變小是毫無意義的,因為即使你完全不管他們,也不會對答案造成任何影響,白白浪費費用

可以考慮二分答案列舉中位數是啥,然後嘗試將前半段每個數都除到中位數以下,計算最小花費

可以注意到的是,如果一個數 \(a_i\) 除以 \(x\) 能到達中位數以下,那麼 \(\ge x\) 的數都能做到,這告訴我們兩點:一是可以二分答案求解這個 \(x\),二是我們應該在所有這些合法的裡面取一個費用最小值,對費用做字尾 \(\min\) 即可

然後由整除分塊經典結論,\(\lfloor{\frac{\lfloor{\frac{a}{b}}\rfloor}{c}}\rfloor=\lfloor{\frac{a}{bc}}\rfloor\),因此有可能提供的這個花費並不是最優花費,比如如果 \(cost_6\gt cost_2+cost_3\),這時用 \(6\) 就不如用 \(2\)\(3\),因此考慮分解其質因數,用質因數花費之和來更新當前值的花費

需要注意的是值域並不只到 \(V\),一個 hack 是 \(V\) 很小,\(a_i\) 很大,值域開小了可能出現超過二分上界的問題(即一個數需要被除很多次)

flowchart TB A(異或連通) style A color:#ffffff,fill:#00c0c0,stroke:#ffffff

線段樹分治

按照線段樹分治的思路直接做

這道題的難點在找到操作會影響哪些區間,上個結論

操作影響的區間一定形如若干連續段,且連續段不超過 \(\log\)

證明:考慮拆位,操作 \(s\) 滿足 \(s\operatorname{xor}x\lt K\),當且僅當存在某一位 \(i\),使得對於任意更高位 \(j\)\(s_j\operatorname{xor}x_j=K_j\),且 \(s_i\operatorname{xor}x_i=1,K_i=0\)

如果我們對詢問建一顆 Trie 樹,符合要求的詢問一定對應 Trie 上某個子樹,如果我們事先對詢問排序,那麼對應的就是一個連續的區間了,由於 Trie 深度最高 \(\log\),因此連續段也不超過 \(\log\)

因此,本題的方案就是:對詢問建立 Trie 樹,找到詢問區間,然後直接線段樹分治即可

flowchart TB A(民主投票) style A color:#ffffff,fill:#00c0c0,stroke:#ffffff

按照題目給的 “每個人只能投給父節點” 投票,我們可以透過二分答案計算出一個最大得票數量的最小值(意思就是把票儘可能均攤給每個人,讓得票最多的那個人得的最小),記這個值為 \(s\)

記一個節點的子樹大小為 \(s_i\)(不包含自己,因為自己無法給自己投票),現在我們要想讓 \(i\) 贏,可以分成以下情況:

  • \(s_i\gt s\),然而我們剛才得到的最大的票數量是 \(s\),說明 \(i\) 最多隻拿了 \(s\) 票,那麼子樹內就一定存在節點將票投給了 \(i\) 的祖先,現在這些節點將票收回來,都投給 \(i\)\(i\) 的票數只會增加(並最終大於 \(s\),因為 \(s_i\gt s\)),祖先的票數只會減少,最終 \(i\) 可能是勝出者
  • \(s_i\lt s\),和上述情況類似,即使子樹內所有票都投給了 \(i\),仍然不滿足 \(s_i\ge s\),而子樹內更不可能有 \(s_i\ge s\) 的節點,但是現最大票數為 \(s\),說明子樹外一定有票數為 \(s\) 的節點,\(i\) 一定失敗
  • \(s_i=s\),此時需要特殊判斷,這種情況下 \(i\) 想要勝出,可以先欽定最大票數只有 \(s-1\) 票,這樣多出來的票會彙集到根節點,此時欽定 \(i\) 獲得了 \(s\) 票,並且由於子樹外最大票數是 \(s-1\) 票,因此 \(i\) 自己那一票只能直接傳到根節點,否則不會勝利

相關文章