3 28 模擬題解

2022-10-11 14:09:14 字數 773 閱讀 7656

a. border

k-substring的答案為 \(f(k)\),則有 \(f(k)\le f(k+1)+2\),因為 \(f(k+1)\) 至少都可以從 \(f(k)\) 繼承而來。

那麼考慮倒序列舉 \(k\) 並計算 \(f(k)\),我們可以先將 \(f(k)\) 設定成 \(f(k+1)+2\),再不停將 \(f(k)\) 減小直到其合法。

如果用雜湊來判斷兩個字串是否相等,則複雜度就是線性的,可以用均攤的思想證明。

這道題的總結是,碰到形如對字串的所有同型別子串求答案的題,

就可以考慮充分利用所有已知資訊,來從乙個子串的答案推到另乙個的答案。

b. majority

首先注意到,乙個區間最多存在乙個絕對眾數,故考慮列舉眾數 \(x\),

並記 \(b_i=[a_i=x]-[a_i\ne x]\),則問題等價於算 \(b\) 中和大於 \(0\) 的區間個數。

記 \(c(x)\) 為序列中 \(x\) 的出現次數,則若以 \(o(c(x)\log n)\) 的複雜度算 \(x\) 的答案,則總複雜度就是 \(o(n\log n)\)。

具體的,對固定的 \(x\),\(b\) 序列形如 \(o(c(x))\) 個連續段,每個連續段的開頭是 \(1\),其餘都是 \(-1\),

而維護乙個連續段對答案的貢獻,等價於區間修改與求二維字首和,

這可以用差分轉化成單點修改與求三維字首和,用樹狀陣列即可,

亦可轉化為區間加等差數列區間求和,用線段樹也能實現。總結是可以考慮維護變化量較小的量。

模擬17 題解

t1 a.入陣曲 60 演算法 維護一下某一列的從第一行到這一行和二維字首和 然後列舉上下左右邊界,o n 4 100 演算法 省掉左右邊界的列舉,改為從左向右掃一邊,記錄總和 k的餘數,並放入桶中,可以發現,如果這個值出現過,那說明這個位置的總和減去那個位置的差 即這個區間 是k的正倍數 t2又是...

模擬16 題解

貪心,對於每只青蛙,跳的時候盡量遠,越遠選擇越多 注意若用set實現,要先insert 0 1 include2 include3 include4 include5 include6 include 7 define r register 8using namespace std 9 inline...

模擬113 題解

手玩發現這個東西好像有一點規律。考慮在最優的方案下,每增加乙個點對答案的貢獻 0 1 然後隨便寫寫就好了。把 x 向 x 能偷的節點建邊。發現這個東西一定會形成森林,其中一些樹為基環樹,其餘為普通形態的樹。對於普通形態的樹,顯然可以賺到其中所有能賺的錢。但基環樹對應著不能從環上乙個節點偷另乙個節點。...