\(Day1\)
報到日 , 無訓練。
\(Day2\)
訓練得分 \(100 + 100 + 0 = 200\)。
\(A.\)
將每個函數映射成一個數 , 可以通過 \(std::map\) 來實現。
轉化后的問題相當於 \(DAG\) 路徑計數。 時間復雜度 : \(O(N)\)
\(B.\)
容斥原理。
首先預處理每個點的概率 , 然后對於每組和整體分別容斥即可。 時間復雜度 : \(O(N ^ 2)\)
\(C.\)
設定閾值跑最短路。
時間復雜度 : \(O(NB)\)
\(Day3\)
訓練得分 \(80 + 50 + 50 = 180\)。
\(A.\)
首先在原樹的基礎上建出一棵新樹 , 新樹上每個點連向原樹上恰好權值大於它的 , 最近的祖先節點。 可以通過倍增得到。
對於 \(Q\) 個詢問 , 先在新樹上倍增找到第一個權值比 \(C\) 大的節點。 然后繼續倍增向上跳到第一個深度比 \(U\) 小的節點即可。
時間復雜度 : \(O(NlogN)\)
\(B.\)
首先可以證明最小的環是三元環。 這是因為如果 \(n(n \geq 4)\) 元環存在 , 則一定存在 \((n - 1)\) 元環。 否則就沒有環存在。
問題轉化為了競賽圖上的三元環計數。 有一個經典的容斥原理做法 ,假設邊集已經確定, 那么 :
\(ANS = {n \choose 3} - \sum{deg_{u} \choose 2}\)。
可以畫圖理解。
那么根據期望的線性性 , 就只需對每個點維護其已確定的出邊和不確定的出邊即可。
時間復雜度 : \(O(N)\)
\(C.\)
首先考慮 , \({a_{i} + b_{i} + a_{j} + b_{j} \choose a_{i} + b_{i}}\) 這個式子等價於從 \((-a_{i} , -b{i})\) , 每次向右或向上 , 到達 \((a_{j} , b_{j})\) 的方案數。 可以根據組合意義來理解。 根據這個結論 , 直接求解 \(NE \ Lattice \ Path\) , 可以得到 \(50\) 分。
考慮從第四象限到第一象限的一條路徑 , 我們發現其一定經過 \(y = -x\) 這條直線。 那么不妨對於直線上每個點維護方案數。 由於 \(\sum{a_{i}} + \sum{b_{i}}\) 不超過 \(2 * 10 ^ 6\) , 因此總的加點更新次數也不超過這個值。
時間復雜度 : \(O(\sum{a_{i}} + \sum{b_{i}})\)
晚上做了一下 \(CEOI\) 的兩道題。
\(The \ Potion \ of \ Great \ Power.\)
用平衡樹維護每對關系的出現時間。
對時間軸建立 \(N\) 棵線段樹 , 我們只需將平衡樹上的點加入線段樹就可以維護出每個人在任意時刻的所有 "朋友"。
由於每個人每個時刻最多有 \(500\) 個朋友 , 因此只需在線段樹上查詢根到其的路徑 , 得到它的朋友的 \(h_{i}\)值。
然后 \(Two-Pointers\) 掃描 ,即可。時間復雜度 : \(O(ND)\)
\(Spring \ Cleaning\)
首先有一個結論 , 對於 \(size\) 值為奇數的節點需要被覆蓋一次 , 偶數的要覆蓋兩次。
這是為什么呢? 可以考慮直接構造 , 對於 \(size\) 為偶數的節點, 將其子樹向上的鏈兩兩配對留下一組。否則將這些鏈兩兩配對最后留下 \(1\) 條鏈。
顯然這樣是最優的。
那么只需樹鏈剖分 + 線段樹維護即可。 也可以建出虛樹進行樹形 \(DP\) 以獲得更優的復雜度。
時間復雜度 : \(O(QlogN)\)
\(Day4\)
訓練得分 \(100 + 40 + 29 = 169\)。
\(A.\)
因為是一棵樹 , 所以對於每個詢問 ,
\(聯通塊數量 = (R - L + 1) - 兩個端點都在[L , R]區間內的邊數\)。
二維數點即可 , 可以離線后用樹狀數組統計。
時間復雜度 : \(O(QlogN)\)
\(B\)
首先考慮一個容斥原理的做法 , 對行列容斥 , 枚舉容斥了 \(i\) 行和 \(j\) 列 , 那么相當於將這 \(i\) 行和 \(j\) 列的限制減去了 \(1\)。可以得到 \(10\) 分。
注意到每個位置的取值之和其行和列的最小值有關 , 它們互相獨立。
因此枚舉行和列中小的值 , 進行上述的容斥原理。 通過乘法原理把容斥得到的值乘起來即可。
時間復雜度 : \(O(N ^ 3logN)\)
\(C\)
提交答案題。
前 \(6\) 個點高精度算 \(2\)的次冪。
后面的點可能需要用到 \(Method \ of \ four \ Russians\) ?
下午做了兩個題 :
\(Calc\)
來自於 \(2012\) 年的國家集訓隊互測。
首先我們設 \(f(n , A)\) 表示前 \(n\) 個數構成遞增序列 , 其中第 \(n\) 個數的值不超過 \(A\) 的序列乘積和。 這是無序的情況 , 那么有序的情況答案就是 \(f(n , A) * n!\)
有轉移方程 : \(f(n , A) = f(n , A - 1) + f(n - 1 , A - 1) * A\)。 這是通過枚舉第 \(n\) 個數得到的。
注意到 \(n\) 很小 , 但是 \(A\) 很大 , 不難想到插值。
引理 : \(f(n)\) 的每個位置的取值是一個 \(2n\) 次多項式的點值。
證明 : 將轉移方程移項得到 : \(f(n , A) - f(n , A - 1) = f(n - 1 , A - 1) * A\)。 我們知道對於一個 \(n\) 次多項式 \(P(x)\) , 有 \(P(x) - P(x - 1)\) 是關於 \(x\) 的 \((n - 1)\) 次多項式。 所以 如果設 \(f(n)\) 的次數為 \(g(n)\) , 就有 \(g(n) - 1 = g(n - 1) + 1\) , 而顯然又有 \(g(0) = 0\) , 因此 \(g\) 是公差為 \(2\) 的等差數列。
因此只要求出 \(f(n , \Delta)\) , 其中 \(\Delta \leq 2n\) , 然后通過拉格朗日插值求出答案。 插值公式和定理就不贅述了。
時間復雜度 : \(O(N ^ 2)\)
\(LOJ2977\)
來自於清華集訓 \(2017\) 。
我們注意到如果顏色數量不大那么顯然是可以求最小斯坦納樹的。
對於顏色數量很大的情況 , 我們將每種顏色隨機映射為 \([0 , K]\) 中的一個整數。 再求解斯坦納樹問題。 這樣一次隨機的正確率是 \(K! \over K ^ K\)。
執行上述過程 \(150\) 次以上 ,答案的正確率超過 \(99.99\%\) ,那么就可以順利通過這道題了。
時間復雜度 : \(O(NM * 2 ^ K)\)
\(Day5\)
訓練得分 \(87 + 91 + 0 = 178\)。
\(A.\)
發現如果 \(t\) 時刻成立 , 那么在 \((t + 1)\)時刻也必然成立。
這是為什么呢? 假設 \(t\) 時刻選出的函數的 \(k\) 值和比 \(0\) 大 , 那么 \((t + 1)\) 時刻顯然也是成立的。 否則 \(0\) 時刻顯然也是滿足的 , 與 \(t\) 時刻是最小滿足的點矛盾。
因此雖然不滿足單調性 , 但是是可二分的。
因此首先判斷 \(0\) 時刻是否可行 , 再進行二分求解即可。 注意二分中的排序我們並不需要用快速排序算法 , 只需要用\(GNU \ C++\)自帶的 \(std :: nth \underline{} element\) 函數即可。
時間復雜度 : \(O(NlogN)\)
\(B.\)
首先可以將每個點用 \(x_{1}\) 表示出來 , 形如 \(x_{i} = k_{i} * x_{1} + w_{i}\) 其中 \(k \in \{-1,1\}\)。
\(k_{i}\) 的符號和節點在樹中的深度有關 , 而對於修改操作 , 又可以看做對子樹中深度為奇數 / 偶數的節點的 \(w\) 值做加法 / 減法。可以通過 \(DFS\) 序 + 樹狀數組 的方式求得。
對於每個詢問 , 根據節點奇偶性討論解方程即可。 細節較為繁瑣 , 需要精細實現。
時間復雜度 : \(O(MlogN)\) , 需要注意常數優化 ,因為輸入量較大 , 可以使用 \(\mathbb{fread}\) 讀入。
\(C.\)
首先枚舉矩形橫向的 \(L\) 和 \(R\)。
對這兩條線進行掃描線 , 枚舉兩條線中最靠下的那個點 ,計算其對答案的貢獻即可。
可以用數據結構來優化這個過程。
細節很多 , 需要精細實現。
時間復雜度 : \(O(NMlogN)\)
\(Day6\)
\(AGC039F\)
首先定義 \(a_{i}\) 為第 \(i\) 行最小的數 , \(b_{j}\) 為第 \(j\) 列最小的數。
算恰好等於是很復雜的 , 我們考慮至少的情況 , 那么
其權值為 \(\prod_{i=1}^n\prod_{j=1}^m{a_{i}b_{j}}\) , 方案數為 \(\prod_{i=1}^n\prod_{j=1}^m{(D - max\{a_{i} , b_{j}\} + 1)}\)。
考慮容斥原理 , 我們容斥一行或一列 , 則相當於將其限制加上了 \(1\)。
考慮直接動態規划 , 令 \(f_{i,j,k}\) 表示使用了 \([1 , i]\) 范圍內的權值 , \(j\) 行 \(k\) 列的答案 , 那么每次就只需要枚舉加入的行數 ,加入的被容斥的行數 , 加入的列數 , 加入的被容斥的列數即可。
這樣復雜度是不能接受的 , 但我們可以分 \(4\) 個階段轉移並預處理轉移系數。
時間復雜度 : \(O(N^3)\)
\(AGC036C\)
首先有一個結論 , 一個序列合法當且僅當其長度為 \(N\) , 最大值不超過 \(2M\) , 奇數的個數不超過\(M\)。
考慮證明 , 必要性顯然 , 充分性可以構造證出。
忽略最大值的限制 , 定義 \(F(N , M , K)\) 表示 \(N\) 個數 , 和為 \(M\) , 奇數的個數不超過 \(K\) 的方案數。 只需用一些組合數的技巧 , 就可以在 \(O(N)\) 的時間內解出這個函數。
然后再考慮最大值 , 考慮容斥原理 , 用合法減去不合法 , 枚舉最大的那個數 , 將其減去 \(2M\) (因為這樣不會對奇偶性的限制造成影響)。
我們要求的是剩下的 \(N\) 個數和為 \(M\) , 奇數個數不超過 \(M\) ,且枚舉的數比 \(0\) 大的方案數。
考慮再進行一次容斥原理 , 用 \(F(N , M , M) - F(N - 1 , M , M)\) , 就得到了上面要求的。
綜上 ,答案為 \(F(N , 2M , M) - N(F(N , M , M) - F(N - 1 , M , M))\)。
預處理組合數即可 , 時間復雜度 : \(O(N)\)。
\(Day7 - Day13\)
軍訓。
\(Day14\)
正睿十連測第三場 :
\(A\)
直接給出結論 , 當 \(M = 0\) 時不可能 , 否則一定有一種方案。
可以構造證明。
還有一種證明方法是求出期望的符合要求邊數是 \(M \over 2\) , 因此除了 \(M = 0\) 的情況 , 其它都一定有一組解。
時間復雜度 : \(O(1)\)
\(B\)
首先我們發現操作是可逆的.
因此我們定義 \(f(s)\) 表示字符串 \(s\) 通過題目中描述的操作所能得到的 , 字典序最小的串。問題轉化為是否有 \(f(a) = f(b)\)。
注意 , 這里的"字典序" 是指在 \(0\) 的個數最多的情況下 , \(1\) 的位置盡可能靠前。
發現如果有連續的 \(k\) 個 \(0\) 后面跟着一個 \(1\) , 那么就可以用這個 \(1\) 和前面的第一個位置交換。
因此 , 直接用堆棧模擬這個過程 , 每次遇到 \(k\) 個連續的數就彈棧。
時間復雜度 : \(O(N)\)
\(C\)
首先記"不屬於"關系的集合為 \(A\) , "屬於" 關系的集合為 \(B\)。
考慮集合 \(B\) , 將集合中的值排序后 , 公差顯然為 \(gcd(b_{1} - b_{0} , b_{2} - b_{1} , b_{3} - b_{2} , .... , b_{n} - b_{n - 1})\) 的約數。
不妨考慮枚舉公差 , 對於每種差值 , 計算可能的序列有多少種。
於是考慮集合 \(A\) , 枚舉其中的每一個元素 , 算出左右端點的取值范圍即可。
時間復雜度 : \(O(M \sqrt{M})\)
\(CF1406E\)
交互題。
首先線性篩 , 求出 \(N\) 以內的所有質數。
將質數分為 \(\sqrt{M}\) 塊。
枚舉最小質因子 , 每次可以先將序列中最小質因子在塊內的數去除 , 再通過詢問 \("A \ 1"\) 來判斷 \(x\) 是否有塊內的因子。
最后我們枚舉 \(x\) 的每個質因子 , 通過 \(A\) 類詢問求出其次冪 , 再將這些值相乘 , 即可。
總操作數 \(M + 2\sqrt{M} + log(M)\)
代碼 : https://codeforces.ml/contest/1406/submission/92755571
\(AGC035F\)
首先設 \(a_{i}\) 表示第 \(i\) 行染的長度 , \(b_{j}\) 表示第 \(j\) 列染的長度。
若 \(a_{i} = j - 1 , b_{j} = i\) , 那么令 \(a_{i} = j , b_{j} = i - 1\) 可以獲得同樣的效果。
結論 :
答案為不存在 \(a_{i} = j - 1 , b_{j} = i\) 這樣情況的方案數。
證明 :
我們設兩個不同的染色方案 \(a , b , a' , b'\) 的作用相同。
找到最小的 \(b_{j} \neq b_{j}'\) , 令 \(b_{j} < b_{j}'\) , 並記 \(r = b_{j}\)。
因為兩個網格同構 , 所以有 \(a_{r} \geq j , a_{r}' < j\)。
若 \(j = 1\) , 則 \(a_{r}' = 0\) , 矛盾。
若 \(j > 1\) , 則 \(a_{r}' < j - 1\) , 而 \(a_{r} \geq j , b_{j} = b_{j - 1}\) , \((r , j - 1)\) 位置在兩種方案下取值不同 , 矛盾。
有了這個結論后 , 就可以進行容斥原理 / 二項式反演了 , 答案為 :
\(\sum{ {n \choose i}{m \choose i}i!(m+1)^{(n-i)}(n+1)^{(m-i)} }\)。
預處理階乘 ,階乘逆元 , \((n + 1) , (m + 1)\) 的冪次即可。
時間復雜度 : \(O(NlogN)\)。
代碼 : https://atcoder.jp/contests/agc035/submissions/16747257
\(Day15\)
訓練得分 : \(100 + 80 + 100 = 280\)。
\(A\)
令 \(dp_{i}\) 表示前 \(i\) 個 , 最小代價是多少。
\(dp_{i} = \min(dp_{j - 1} + K + S(mx - mn))\)。
時間復雜度 : \(O(NM)\)。
\(B\)
首先建出最短路徑生成樹。
每次刪除一條邊 , 運行 \(BFS / DFS\) , 將生成樹上影響到的節點刪除即可。
時間復雜度 : \(O(N + M)\)
\(C\)
首先枚舉對角線。
然后枚舉右下角 , 計算左上角對其的貢獻。
用掃描線 \(+\) 樹狀數組統計即可。
時間復雜度 : \(O(NMlogN)\)。
\(AGC007E\)
首先二分答案 \(mid\)。
設 \(dp_{u , l , r}\) 表示以 \(u\) 為根的子樹 , 第一次走到了葉子節點 \(l\) , 最后一次走到葉子節點 \(r\) , 每次經過邊權不超過 \(mid\) , 是否可行。
這個動態規划該如何轉移? 顯然可以直接考慮左邊和右邊 , 兩兩合並即可。
這樣做是 \(O(N ^ 3logN)\) 的。
考慮優化 , 首先觀察到一個性質 :
如果有兩個可行狀態 \(dp_{u,l1,r1}\) 和 \(dp_{u,l2,r2}\) , 滿足 \(l1 \leq l2 , r1 \leq r2\) , 那么后者是無用的。
這個結論顯然正確。
因此將可行的狀態按 \(l\) 排序 , 右端點必然單調遞減。
這樣我們就可以枚舉一個子樹的 \(l\) , 在另一棵子樹中 , 找到左端點最大的與其匹配即可。 可以用 \(Two-Pointers\) 優化。
然后注意到另一個性質 : 一個子樹 \(S\) 的可行狀態數是 \(2|S|\) 級別。
用類似啟發式合並的復雜度分析可以證明 , 這個做法的時間復雜度是 \(O(Nlog^2N)\)。
\(Day16\)
訓練得分 : \(100 + 100 + 100 = 300\)。
\(A\)
不難證明能往后放就盡可能往后一定是最優的。
預處理前 \(20\) 個菲波那契數 , 哈希 / 平衡樹求解。
時間復雜度 : \(O(NlogN)\)。
\(B\)
將字符串 \(A\) 中每個字母映射到 \(B\) 中去。 樹狀數組 / 歸並排序求逆序對數即可。
時間復雜度 : \(O(NlogN)\)
\(C\)
首先簡化題意。 將圓上問題轉化為序列上的問題。
每個操作相當於給數軸上一段區間插入一個數。 那么相當於在 \(l\) 處插入一個數 , 在 \(r\) 處刪除這個數。
對於每一個划分段分別統計答案 , 我們要求的是覆蓋它的數(圓)中半徑第 \(K\) 大的。
在樹狀數組上二分即可 , 還有一種做法是用堆來實現 , 當堆的大小小於 \(K\) 時 , 將前面一段的答案一起計算。
時間復雜度 : \(O(NlogN)\)。
\(Day17\)
訓練得分 : \(0 + 0 + 60 = 60\)。
\(A\)
結論 \(1\) : 一個"好" 數必然是另一個 “好” 數乘上一個質數。
結論 \(2\) :一個 \(10 ^ {18}\) 以內的"好"數的最大質因子不超過 \(67\)。
暴力搜索即可。 時間復雜度 : \(O(KlogK)\)
\(B\)
考慮將兩個數組分別從大到小排序。
對於每個請求 , 取出符合條件中最小的那個 , 並將 \((val - w)\) 放入一個大根堆 , 如果沒有 , 就使用一次修改。
最終取出堆中最大的 \(K\) 個值 , 將其減去。
時間復雜度 : \(O(NlogN)\)。
\(C\)
我的做法 :
首先最優方案必然是一個子樹中選取一個點 , 再在另外一部分中選一個點。
在這兩個點的 \(LCA\) 上統計答案。 做樹形 \(DP\) 即可。
按照題目中所述的生成方式 , 樹高不超過 \(logN\) , 每個節點的子節點個數不超過 \(ln N\)。
固時間復雜度 : \(O(Nlog^3N)\)。
標准做法 :
延續剛才的思路 , 枚舉一條斷邊。 對於剩下的兩部分分別求帶權重心即可。
這個做法的時間復雜度 : \(O(NlogN)\) , 可以通過 \(D = 100\) 的數據。
\(CF1053C\)
首先考慮一個經典問題 :
\(|a_{1} - x| + |a_{2} - x| + |a_{3} - x| + ..... + |a_{n} - x|\) 的最小值是多少?(x為整數)
顯然當 \(x\) 取 \({a}\) 的中位數最優。
接着 , 考慮帶上權值怎么做 , 即 :
\(w_{1} \cdot |a_{1} - x| + w_{2} \cdot |a_{2} - x| + ..... + w_{n} \cdot |a_{n} - x|\) 的最小值。
那么 \(x\) 的值取 \(\sum_{i=1}^{x}{w_{i}}\) 恰好大於等於 \(\sum_{i=x+1}^{n}{w_{i}}\) 時最小、
這是因為如果 \(x\) 右移時式子的值會減小。
那么這個題怎么做呢?
將一段區間整體移動 , 相當於先移動到一個固定的點再調整 , 因此轉化為了上述問題。
列出答案的式子 , 化簡后發現只要知道 \(\sum{w_{i}}\) 和 \(\sum{w_{i} - i}\) 即可 , 可以使用兩個支持單點修改區間查詢的數據結構維護 , 那么樹狀數組不失為一個不錯的選擇。
時間復雜度 : \(O(NlogN)\)。
\(Day18\)
訓練得分 : \(70 + 100 + 40 = 210\)。
\(A\)
考慮當前一個數 \(x\) , 有四種轉移 :
\(1.\) 花費 \(1\) 步 , 將這個數加一。
\(2.\) 花費 \(1\) 步 , 將這個數減一。
\(3.\) 花費 \(4\) 步將其復制 , 再用 \(2k\) 步將其乘 \((k + 1)\)。
\(4.\) 花費 \(3\) 步將其清零。
那么直接運行最短路即可。
用 \(SPFA\) 算法 + \(SLF\)優化可以獲得比 \(Dijkstra\) 更優的復雜度。
時間復雜度 : \(O(NlogN)\) (存在很小的常數)
\(B\)
我的做法 :
建圖二分圖匹配。
時間復雜度 : \(O(N ^ 2)\)。
\(C\)
首先觀察到答案不超過 \(2n\) , 這是因為每次取最大的最多只需用 \(2\) 次操作就能換到其對應的位置。
因此迭代加深 + \(DFS\) 就可以得到 \(40\) 分。
接着 , 我們注意到每次交換后 , 最多只有一個 \(|a_{i} - a_{i - 1}|\) 的值發生改變。
因此可以將估價函數定義為 \(|a_{i} - a_{i - 1}|\) 不為 \(1\) 的個數。
\(IDA*\)即可 , 時間復雜度 : \(O(?)\)
\(CF1139F\)
首先考慮題目中給出的條件 :
\(p_{i} \leq inc_{j} \leq s_{i}\)
\(|b_{i} - pref_{i}| \leq (inc_{j} - p_{i})\)
顯然可以將絕對值展開 , 那么 , \(i\) 對 \(j\) 產生貢獻當且僅當
1). \(p_{i} \leq inc_{j} \leq s_{i}\)
2). \(inc_{j} + pref_{j} \geq b_{i} + p_{i}\)
3). \(pref_{j} - inc_{j} \leq b_{i} - p_{i}\)
考慮這三個條件的含義 , 將 \(inc\) 值作為橫軸 , \(pref\) 值作為縱軸 , 發現 \(i\) 能夠造成的貢獻的點恰好為平面上的一個等腰三角形。如圖(來自陳櫛曠) :
考慮掃描線並進行差分 , 在掃描到 \(b_{i}\) 時加入這個三角形 , 在掃描到 \(s_{i} + 1\) 時去除這個三角形所造成的影響。
除此以外 , 還需要支持查詢某個點在多少個三角形內。
於是考慮第 \(i\) 個三角形造成的影響 , 可以看成
1). 在直線 \(x + y = b_{i} + p_{i}\) 上貢獻 \(1\)。
2). 在直線 \(y - x = b_{i} - p_{i} + 1\) 上貢獻 \(-1\)。
詢問相當於詢問橫坐標為 \(inc_{j}\) , 縱坐標不超過 \(pref_{j}\) 的貢獻之和。
那么對於 \(x + y\) 和 \(y - x\) 分別維護一個樹狀數組即可。
時間復雜度 : \(O(NlogN)\)。
\(Day19\)
\(AGC022E\)
考慮給定一個序列 , 判斷其是否合法。
不妨維護一個棧。
如果加入的數是 \(0\) :
如果棧頂已經有兩個 \(0\) , 將三個數 \(0\) 合並為一個 \(0\)。
否則加入這個 \(0\)。
如果加入的數是 \(1\) :
如果棧頂是 \(0\) , 那么刪除這個 \(0\) , 因為這三個數的中位數取決於下一個數。
否則加入這個 \(1\)
那么就有一個動態規划的思路了 :
記 \(dp_{i , j , k}\) 表示前 \(i\) 個數 , 棧中有 \(j\) 個 \(0\) , \(k\) 個 \(1\) , 有多少種不同的序列。
\(j\) 和 \(k\) 不超過 \(3\) , 因此時間復雜度 : \(O(N)\)。
事實上這個轉移可以看做有限狀態自動機 , 可以矩陣乘法做到 \(O(logN)\) 級別 , 不過放在這題沒有必要了。
\(AGC030F\)
首先如果兩個數都已經確定 , 那么顯然可以去除。
那么剩下的數就是兩個數中只有 \(1\) 個不確定的和兩個都不確定的。 將只有一個數不確定的組中 , 不為零的那個數的 \(v\) 值標記為 \(1\)。
將 \(1 - 2N\) 順次排成一排 , 配對的連一條線 , 那么 , \(B\) 中的元素就是每條線的左端點的值。
如果這條線兩端的值都沒有在 \(A\) 中,那么我們先不給這條線賦值,等到最后統計完所有方案后,可以發現這樣的線的個數是確定的(就等於 \(N\) 減去一端在 \(A\) 中的數對的數量),假設為 \(|S|\) ,把答案乘以 \(|S|!\) 就行了。
兩個方案不同當且僅當 :
1). 有一個點在第一個方案中是左端點 , 而在另一個方案中不是左端點。
2). 兩個左端點所在的線的編號不同。
考慮從大到小動態規划 , 記 :
\(dp_{i , j , k}\) 表示大於等於 \(i\) 的數中 , 有 \(j\) 個 \(v_{x} = 0\) 的點沒配對 , 有 \(k\) 個 \(v_{x} = 1\) 的點沒配對。
時間復雜度 : \(O(N ^ 3)\)
\(CF1227F\)
首先將 \(A\) 類區間和 \(B\) 類區間分別插入兩棵不同的線段樹。這兩棵樹的值域為 \([0 , 2 ^ {60}]\) , 這樣每個節點的長度都是二的次冪。
將輸入區間拆成的次冪對應在線段樹上的節點標記為黑色節點。
考慮兩個節點的貢獻 , 顯然和深度較小的那個節點有關。
那么就有一個 \(O(N^2L^2log(N^2L^2))\)的思路了 :
枚舉兩棵樹上的兩個黑色節點 , 那么對一個形如 \([x , x + 2 ^ {d}]\) 的區間造成了貢獻 , 這也對應了一個線段樹上的節點。
以線段樹上 \(DFS\) 序從小到大的順序枚舉計算即可 , 具體而言 , 就是如果一個節點的祖先節點沒被標記 , 就加上它的貢獻。
然而這樣是不能通過的。 需要發現一些其他性質 :
考慮兩個節點 \(p , q\) , 其中 \(dep_{p} < dep_{q}\) , 那么將 \(q\) 變成它的父親節點所造成的貢獻是相同的。
因此可以換一種枚舉方式 :
枚舉兩個節點 \(p , q\) , 其中 \(dep_{p} = dep_{q}\) , 並且\(p\) , \(q\)中有一個黑色節點。 計算這兩個點形成的異或區間。
這樣復雜度是 : \(O(N ^ 2Llog(N^2L))\)。
\(LOJ2743\)
一個經典問題 , 來自於\(2016\)年日本信息學競賽(\(JOI\))夏令營。
考慮將 \(A\) 從小到大排序 , 依次加入這個序列。
如圖 , 在 \(A_{i}\) 不斷增大的過程中 , 維護直線 \(y = A_{i}\) 下方的長度和。
於是定義 \(DP\) 狀態 \(f_{i , j , k , h}\) , 表示插入了 \(i\) 個數 , 分成了 \(j\) 個聯通塊 , 當前的總和為 \(k\) , 選出了 \(h\) 個邊界的方案數。
這樣定義狀態的好處是 , 只需保證兩段之間有空位或是否在邊界即可 , 而並不關心其實際位置。
不難發現 , 每次從 \(f_{i}\) 轉移至 \(f_{i + 1}\) , 每段會增加 \(A_{i + 1} - A_{i}\) , 因此貢獻為 \((2j - h)(A_{i + 1} - A_{i})\)。
具體轉移不再贅述了 , 需要分 \(5\) 類情況討論。
時間復雜度 : \(O(N ^ 2L)\) , 可以使用滾動數組優化第一維空間。
\(Day20\)
整理山東省隊集訓題
\(Day21\)
訓練得分 : \(70 + 80 + 60 = 210\)。
\(A\)
記 \(dp_{S , i}\) 表示當前隊列里人的集合為 \(S\) , 有 \(i\) 個不滿足關系的方案數。
時間復雜度 : \(O(2^NN^2)\)。
\(B\)
對於每個右端點計算其貢獻。
維護兩個單調棧和支持區間賦值 , 詢問區間和的最大 / 最小線段樹。
時間復雜度 : \(O(NlogN)\)
\(C\)
考慮期望的線性性 , 有 \(E(A) = \sum{E(A_{i})} = \sum\sum{E(A_{i} , A_{j})}\)。 其中 \(E(A_{i} , A_{j})\) 是 \(A_{j}\) 排在 \(A_{i}\) 之前的概率。
考慮一個 \([L_{i} , R_{i}]\) 的貢獻 , 是一個等差數列 + 一段區間加同一個數的形式。
那么維護一棵支持區間加法和區間加等差數列的線段樹即可。
時間復雜度 : \(O(NlogN)\)
\(Day22\)
訓練得分 : \(100 + 0 + 100 = 200\)。
\(A\)
求 \(AND\) 的最大值 , 顯然可以從高到低判斷是否每一位能為 \(1\)。
求 \(OR\) 的最大值 , 可以用高維前綴和解決。
求 \(XOR\) 的最大值 , 可以用 \(Trie\) 樹貪心。
時間復雜度 : \(O(NlogM + 2 ^ M * M)\)
\(B\)
第一個性質 : 每個點無論如何運動 , 排名不變。
第二個性質 : 兩個點相遇后反向運動 , 不考慮編號的情況下 , 等價於兩個點按原來的方向繼續行進。
對於每組詢問二分答案求第 \(K\) 小排名的點即可。
時間復雜度 : \(O(QlogN)\)。
\(C\)
每加一個數的貢獻是 \((A_{i + 1} - A_{i})\)。
設 \(dp_{i , j , k}\) 表示前 \(i\) 個數 , 當前和為 \(j\) , 分成 \(k\) 組的方案數。
分類討論轉移即可。
時間復雜度 : \(O(N ^ 2K)\)。
\(Day23\)
訓練得分 : \(100 + 100 + 0 = 200\)。
\(A\)
將小於 \(b\) 看成 \(-1\) , 將大於 \(b\) 看成 \(1\) , 一段數的中位數為 \(b\) 當且僅當這段的權值和為 \(0\)。
前綴和 + 哈希維護即可。
時間復雜度 : \(O(NlogN)\)
\(B\)
建最短路圖 , \(Tarjan\) 求割邊即可。
時間復雜度 : \(O(N + M)\)
\(C\)
搜索即可。
時間復雜度 : \(O(?)\)。
\(LOJ6039\)
首先發現 \(C_{i}\) 很小 , 因此可以將 \(C_{i}\) 相同的合並。
對於一段 \(C_{i}\) 相同的 , 一定是取最大價值的優先考慮。
於是設 \(f_{i , j}\) 表示小於等於 \(i\) 的權值 , 用了容積 \(j\) , 獲得的最大收益。
按照 \(j\) 模 \(i\) 的意義下分類 , 有 \(f_{i , j} = \max(f_{i - 1 , j},f_{i - 1 , j - ik} + V_{i , k})\)。
注意到 \(V\) 值的斜率是單調不增的 , 因此該轉移具有決策單調性。
那么分治優化決策單調性 \(DP\) 即可。
時間復雜度 : \(O(NMlogN)\)
\(LOJ6029\)
線段樹維護區間的 \(Max\) 和 \(Min\) 值 , 一次除法操作 , 如果區間的最大最小值變化量相同 , 那么相當於區間減操作。
定義一個區間的勢能為 \((Max - Min)\) , 這個區間的勢能變化量不超過 \(log\) 次 , 故時間復雜度 : \(O(Nlog^2N)\)。
\(Day24\) - \(Day27\)
/
\(Day28\)
訓練得分 : \(100 + 10 + 0 = 110\)。
\(A\)
答案一定是相鄰兩個數最優。
線段樹維護即可 , 時間復雜度 : \(O(MlogN)\)
\(B\)
考慮一個非好數 , 將最大數加入這個數的左右兩邊 , 非好數數量不變。
動態規划即可。
時間復雜度 : \(O(N ^ 2)\)
\(C\)
\(S\) 到 \(T\) 的路徑異或和一定是 \(S\) 到 \(T\) 的任意一條路徑異或若干個環的形式。
將環插入線性基 , 按位計算答案。
時間復雜度 : \(O(MlogN)\)
\(Day29\)
訓練得分 : \(100 + 100 + 0 = 200\)
\(A\)
基環樹上的期望問題。
先拓撲排序 , 環上點的期望是一定的 , 先算出環上的期望 , 然后逆着拓撲序計算即可。
時間復雜度 : \(O(N)\)
\(B\)
將曼哈頓距離轉化為切比雪夫距離。
掃描線 + 線段樹計算答案即可。
時間復雜度 : \(O(NlogN)\)
\(C\)
不難發現題目中的條件為兩點在同一個邊 - 雙連通分量中(\(e-DCC\))。 也就是被至少一個環所包含。
首先建出最小生成樹。
用並查集維護每個點向上第一條未被覆蓋的邊。
按邊權從小到大枚舉非樹邊 , 用並查集合並未被覆蓋的邊 , 在合並過程中建出一棵重構樹 , 查詢時求重構樹上最近公共祖先即可。
時間復雜度 : \(O((N + Q)logN)\)