二維莫隊
二維莫隊,顧名思義就是每個狀態有四個方向可以擴展。
二維莫隊每次移動指針要操作一行或者一列的數,具體實現方式與普通的一維莫隊類似,這裏不再贅述。這裏重點講塊長選定部分。
塊長選定
記詢問次數為 \(q\),當前矩陣的左上角座標為 \((x_1,\ y_1)\),右下角座標為 \((x_2,\ y_2)\),取塊長為 \(B\)。
那麼指針 \(x_1\) 移動了 \(\Theta(q\cdot B)\) 次,而指針 \(y_2\) 移動了 \(\Theta(n^4\cdot B^{-3})\) 次。
所以只需令 \(q\cdot B=n^4\cdot B^{-3}\),即 \(B=n\cdot q^{-\frac 14}\) 即可。
注意這樣計算 \(B\) 的結果 可能為 \(0\),注意特判。
最終,計算部分時間複雜度是 \(\Theta(n^2\cdot q^{\frac 34})\),加上對詢問的排序過程,總時間複雜度為 \(\Theta(n^2\cdot q^{\frac 34}+q\log q)\)。
例題 1
BZOJ 2639 矩形計算
輸入一個 \(n\times m\) 的矩陣,矩陣的每一個元素都是一個整數,然後有 \(q\) 個詢問,每次詢問一個子矩陣的權值。矩陣的權值是這樣定義的,對於一個整數 \(x\),如果它在該矩陣中出現了 \(p\) 次,那麼它給該矩陣的權值就貢獻 \(p^2\)。
數據範圍:\(1\leq n,\ m\leq 200\),\(0\leq q\leq 10^5\),\(|\) 矩陣元素大小 \(| \leq 2\times 10^9\)。
解題思路
先離散化,二維莫隊時用一個數組記錄每個數當前出現的次數即可。
示例代碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | |
例題 2
洛谷 P1527 [國家集訓隊] 矩陣乘法
給你一個 \(n\times n\) 的矩陣,\(q\) 次詢問,每次詢問一個子矩形的第 \(k\) 小數。
數據範圍:\(1\leq n\leq 500\),\(1\leq q\leq 6\times 10^4\),\(0\leq a_{i,j}\leq 10^9\)。
首先和上一題一樣,需要離散化整個矩陣。但是需要注意,本題除了需要對數值進行分塊,還需要對數值的值域進行分塊,才能求出答案。
這裏還需要用到奇偶化排序進行優化,具體內容請見 普通莫隊算法。
對於本題而言,時間限制不那麼寬,注意代碼常數的處理。取的塊長計算值普遍較小,\(n,\ q\) 都取最大值時塊長大約在 \(11\) 左右,可以直接設定為常數來節約代碼耗時。
示例代碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用