P7862
答案具有單調性,考慮二分,設為 \(D\)。
如果一個連通塊內有 \(\ge K\) 的點那麼一定可行,有個粗略的證明:每次加進來一個數,如果能湊出的數的集合沒有增大,說明已經存在一種方案使得和 \(=K\)。否則一定會增加一個集合中的數。
而對於一個 \(D \times D\) 的矩形,如果矩形記憶體在至少 \(4K\) 個點,則一定有解。可以按中線劃分成 \(4\) 個子部分。根據鴿巢原理,至少有一個區域含有的點數 \(\ge K\)。
於是用 set
維護一下,每個點最多連出去 \(O(K)\) 條邊,最後對每個連通塊暴力揹包即可,時間複雜度 \(O(N \log N \log V + NK \log V)\)。'
P7619
先想如何確定一個製作訂單的順序,考慮鄰項交換。\((L_i, T_i)\) 在 \((L_j, T_j)\) 前面,當且僅當:
所以按 \(T\) 排序即可,第 \(i\) 個訂單的收益為 \(L_i - \sum\limits_{j = 1}^i T_j\),顯然 \(L_i\) 可以提出去,那麼就要算 \(\sum\limits_{i = 1}^n \sum\limits_{j = 1}^i T_j = \sum\limits_{i = 1}^n T_i \times (n - i + 1)\),用權值線段樹維護即可。
P6371
顯然數位 dp,當 \(X\) 較小 \(\le 10^5\) 時設計 dp 狀態 \(dp(i, 0/1, 0/1, 0/1, j)\) 表示還有 \(i\) 位沒填,是否頂到了下界 \(A\),頂到了上界 \(B\),是否為空(全為前導 \(0\)),模 \(X\) 餘數為 \(j\) 的方案數,轉移好寫。
當 \(X \ge 10^5\) 時直接 \(O(\dfrac{B}{X} \log B)\) 暴力 \(\textrm{check}\) 是否合法即可。
P10977
設計 dp,有 \(dp(i) = \min \{ dp(j) + \max_{k = j + 1}^i a_k\}\),考慮最佳化。
對於帶有 \(max\) 的區間類 dp,可以想 CDQ 分治,每次對於區間 \([l, r]\),記錄:
接著每次判斷 \(\max\) 在左邊和右邊的情況,開些陣列維護一下 \(dp\) 值即可。容易觀察到每次移動指標,區間一定只會擴大,所以不需要線段樹之類的資料結構。時間複雜度 \(O(n \log n)\)。
P9673
重要結論:交換次數是 \(O(n \log n)\) 級別的!!!
證明:假設取的 \(A[mid]\) 排在區間 \([l, r]\) 中的第 \(k\) 位,顯然最多交換 \(\min(k - 1, (r - l + 1) - k)\) 次,所以設長度為 \(n\) 的區間的交換次數級別為 \(T(n)\),有:
\[T(n) = \min_{k = 1}^n \left(T(k - 1) + T(n - k) + \min(k - 1, n - k)\right) \]這是經典的啟發式合併複雜度的式子,所以級別是 \(O(n \log n)\) 的。
問題在於指標移動次數可能是 \(O(n^2)\) 級別的,所以考慮最佳化指標移動的過程。
於是線段樹二分即可,時間複雜度 \(O(n \log^2 n)\)。
P6122
容易建出費用流模型:
- 對於 \(i \in [1, m]\),建立 \(S \to p_i\) 連流量為 \(1\),費用為 \(0\) 的邊。
- 對於原圖的邊 \((u, v)\),建立 \(u \to v\) 和 \(v \to u\) 的流量為 \(\inf\),費用為 \(1\) 的邊。
- 對於每個點 \(x\),建立 \(x \to T\),流量為 \(c_x\),費用為 \(0\)。
這樣每次新加進來一個 \(p_i\) 的時候重新建一遍圖,然後跑 dinic
就能過 \(n \le 100\) 的部分分。考慮最佳化,於是模擬費用流,由於這個圖是一個完全二叉樹,即兩點路徑長度為 \(O(\log n)\),所以記 \(f(i)\) 表示 \(\textrm{argmax}_{j \in subtree(i)} \textrm{dist}(j, i)\),每次更新路徑上的流量並維護一下即可。時間複雜度 \(O(n \log n)\)。
CF1175G
考慮 \(dp\),設 \(dp(i)\) 表示前 \(i\) 個分成若干段的答案,有 \(dp(i) = \min \{ dp'(j) + (i - j) \times \max_{k = j + 1}^i a_k\}\)。看到代價函式中含有區間 \(max\),於是想到 CDQ 分治。
於是類似上面 Cut the Sequence 的思路,處理出 \(max(i)\),內部套一個斜率最佳化即可。時間複雜度 \(O(n k \log n)\)。
CF1214G
顯然存在一組解的充要條件是:存在兩行 \(i, j\) 使得 \(S_i\) 和 \(S_j\) 不相互包含。
有結論:將每行按照 \(1\) 的數量從小到大排序,存在解 \(\Leftrightarrow\) 相鄰兩行合法。
證明:假設有 \(i < j < k\),存在 \(S_i \cup S_k \ne S_i\),並且 \(S_i \cup S_j = S_i \land S_j \cup S_k = S_j\),推出 \(S_i \cup S_k = S_i\) 與假設矛盾。原結論得證。
用 set
和 bitset
維護即可,時間複雜度 \(O(q \log n + \dfrac{n^2}{w})\)。\
ABC374F
模擬賽出了這道題的加強版,把 \(N\) 開到了 \(10^4\) 並且要求 \(O(N)\) 空間複雜度。
於是設 \(dp(i)\) 表示前 \(i\) 個完成,現在的時間為 \(T_i\) 的最小答案。考慮更新 \(dp(j)\) 的值,每次往後走一段,設當前時間為 \(pret\),走到了 \(prex\),答案為 \(prec\),設 \(nxx\) 為 \(T\) 中最後一個 \(\le pret + X\) 的下標,由於每次最多選 \(K\) 個,所以要讓 \(nxx\) 對 \(prex + K\) 取 \(\min\)。每次給 \(prec\) 加上 \((nxx - prex) * T_{nxx}\) 即可,然後更新 \(pret\) 和 \(prex\) 的值。
轉移的時候很好計算貢獻,答案為 \(dp(n) - \sum\limits_{i = 1}^n T_n\),時間複雜度 \(O(N^2)\)。
ABC374G
首先考慮連邊,問題轉化為選擇最少的可交路徑使得一個有向有環圖的每條邊都被覆蓋。顯然一個強連通分量內的邊是可以一次走完的,所以縮點後變為 DAG 的問題。
接著發現這很網路流,考慮將點轉化為邊,邊轉化為點。這樣就變為選最少的可重路徑使得每個點都被覆蓋一次,傳遞閉包一下就轉化為了不可重路徑,點數 \(O(N^2)\),由於 \(N^2\) 只有 \(600\) 所以可過。