Codeforces Round 1016 (Div. 3)題解

題目地址

https://codeforces.com/contest/2093

銳評

在所有題意都理解正確的情況下,整體難度不算太難。但是偏偏存在F這么惡心的題意,樣例都不帶解釋一下的,根本看不懂題。D題也惡心,在于遞歸過程的拆分,需要點數學,跟打印遞歸定義的圖形一樣,寫麻了,好在過了。E題居然卡雙 l o g log log 做法常數,也是惡心。反而是G題很典,太裸了,可惜被D防住了,根本沒看到G題。再次陷入“看完所有題不會寫,不看完所有題卻會寫”的魔咒。主要還是自己太菜了,打破不了這個魔咒,大佬們就沒這個煩惱。

題解

Problem A. Ideal Generator

題目大意

k k k 個正整數組成的數組 a a a [ a 1 , a 2 , … , a k ] = [ a k , a k ? 1 , … , a 1 ] [a_1, a_2, \dots, a_k] = [a_k, a_{k-1}, \dots, a_1] [a1?,a2?,,ak?]=[ak?,ak?1?,,a1?] 的情況下稱為回文數組(其實就是正著讀反著讀是一樣的)。例如,數組 [ 1 , 2 , 1 ] [1, 2, 1] [1,2,1] [ 5 , 1 , 1 , 5 ] [5, 1, 1, 5] [5,1,1,5] 是回文數組,而數組 [ 1 , 2 , 3 ] [1, 2, 3] [1,2,3] [ 21 , 12 ] [21, 12] [21,12] 不是回文數組。

如果任何整數 n n n ( n ≥ k n \geq k nk ) 都可以表示為一個長度正好為 k k k 的回文數組的元素之和,我們就稱這個數 k k k 為理想生成數。數組中的每個元素都必須大于 0 0 0

例如,數字 1 1 1 是一個理想生成數,因為任何自然數 n n n 都可以用數組 [ n ] [n] [n] 生成。然而,數字 2 2 2 并不是一個理想生成數,因為不存在長度為 2 2 2 的和為 3 3 3 的回文數組。

請判斷給定的數字 k k k 是否是理想生成數。

題解思路:思維

先通過樣例觀察,發現奇數可以,偶數不行。開始驗證,假如和為 k k k ,那么全部數組元素為 1 1 1 即可,假如和為 k + 1 k + 1 k+1 ,那么全部數組元素為 1 1 1 的基礎上,有一個數要加上 1 1 1 還要是回文數組,那么只能放在最中間的位置上了,不然所放位置對稱的那一個位置就不相等了。又因為 n n n 是連續的,所以差值為 1 1 1 只有數組長度是奇數才能滿足,每次都在最中間位置加上 1 1 1 。時間復雜度為 O ( 1 ) O(1) O(1)

參考代碼(C++)

#include <bits/stdc++.h>
using namespace std;
int n;void solve() {cin >> n;cout << ((n & 1) ? "YES\n" : "NO\n");
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;cin >> t;while (t--)solve();return 0;
}

Problem B. Expensive Number

題目大意

正整數 n n n 的代價被定義為數字 n n n 除以其數位之和的結果。

例如,數字 104 104 104 的代價是 104 1 + 0 + 4 = 20.8 \frac{104}{1 + 0 + 4} = 20.8 1+0+4104?=20.8 ,數字 111 111 111 的代價是 111 1 + 1 + 1 = 37 \frac{111}{1 + 1 + 1} = 37 1+1+1111?=37

給你一個不包含前導零的正整數 n n n 。你可以從數字 n n n 中刪除任意數位(包括不刪除),這樣剩下的數字至少包含一位數,并且嚴格大于零。剩下的數字不能重新排列。因此,你可能得到一個前導為零的數字。

例如,給你一個數字 103554 103554 103554 。如果去掉 1 1 1 4 4 4 和一個數字 5 5 5 ,最后得到的數字是 035 035 035 ,其代價是 035 0 + 3 + 5 = 4.375 \frac{035}{0 + 3 + 5} = 4.375 0+3+5035?=4.375

為了使代價最小,你需要從這個數字中刪除最少多少個數字?

題解思路:貪心

首先,一個數字的數位之和是不可能大于這個數字的,最多和它相等。那么代價最小意味著什么?顯然就是相等。所以只有一位數字時代價達到最小,代價為 1 1 1 。因為題目刪除數位后允許有前導 0 0 0 ,所以選定某個數字前面的 0 0 0 可以不刪除。又因為題目要求刪除后組成的這個數必須嚴格大于 0 0 0 ,所以我們要找一個非 0 0 0 數位。因為前導 0 0 0 可以保留,后導 0 0 0 不能保留(保留就不是個位數了),所以我們倒著枚舉,找到第一個非 0 0 0 數位位置,將這個位置前面的非 0 0 0 數位刪除以及后面的數位刪除,刪除的數位個數即是答案。時間復雜度為 O ( n ) O(n) O(n)

參考代碼(C++)

#include <bits/stdc++.h>
using namespace std;
string str;void solve() {cin >> str;int n = str.size();int id = n - 1;for (int i = n - 1; i >= 0; --i)if (str[i] != '0') {id = i;break;}int ans = n - 1 - id;for (int i = id - 1; i >= 0; --i)if (str[i] != '0')++ans;cout << ans << '\n';
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;cin >> t;while (t--)solve();return 0;
}

Problem C. Simple Repetition

題目大意

帕夏喜歡質數!為了找到生成質數的新方法,他再次對互聯網上的一種算法產生了興趣:

  • 要得到一個新數字 y y y ,重復 k k k 次數字 x x x 的十進制表示 x x x (不含前導零)。

例如, x = 52 x = 52 x=52 k = 3 k = 3 k=3 可以得到 y = 525252 y = 525252 y=525252 x = 6 x = 6 x=6 k = 7 k = 7 k=7 可以得到 y = 6666666 y = 6666666 y=6666666

帕夏非常希望得到的數字 y y y 是質數,但他還不知道如何檢驗這種算法生成的數字的質性。請幫助帕夏,告訴他 y y y 是否是質數!

如果一個整數 x 只有 2 個不同的除數 1 和 x ,那么這個整數 x 就是質數。例如, 13 是質數,因為它只有 2 個除數: 1 和 13 。請注意,數字 1 不是質數,因為它只有一個除數。

題解思路:思維/分類討論

我們來一一分析下。

  • k = 1 k = 1 k=1 ,顯然只需要判定 x x x 是否質數。
  • k > 1 k \gt 1 k>1 ,即 x x x 至少重復了 2 2 2 次,設 x x x n n n 個數位,那么 y y y 顯然有一個除數 x x x ,使得 y x = a 1 0 ? 0 ? n ? 1 個 a 2 0 ? 0 ? n ? 1 個 … a k \frac{y}{x} = a_1 \underbrace{0 \cdots 0}_{n - 1個} a_2 \underbrace{0 \cdots 0}_{n - 1個} \dots a_k xy?=a1?n?1 0?0??a2?n?1 0?0??ak? ,其中 a i = 1 , 1 ≤ i ≤ k a_i = 1, 1 \leq i \leq k ai?=1,1ik 。那么只要 1 < x < y 1 \lt x \lt y 1<x<y y y y 必然不是質數,顯然 x < y x \lt y x<y 必然成立,所以只需要再單獨判斷一下 x x x 1 1 1 的情況即可。

根據上面的分析,問題得解。時間復雜度為 O ( 1 ) O(1) O(1)

參考代碼(C++)

#include <bits/stdc++.h>
using namespace std;
int n, m;bool check(int x) {if (x < 2)return false;for (int i = 2; i * i <= x; ++i)if (x % i == 0)return false;return true;
}void solve() {cin >> n >> m;if (m == 1)cout << (check(n) ? "YES\n" : "NO\n");else if (n == 1) {int x = 0;for (int i = 0; i < m; ++i)x = x * 10 + 1;cout << (check(x) ? "YES\n" : "NO\n");} elsecout << "NO\n";
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;cin >> t;while (t--)solve();return 0;
}

Problem D. Skibidi Table

題目大意

瓦迪姆喜歡用整數填充方形表格。不過今天他想到了一個好玩的方法!以大小為 2 × 2 2 \times 2 2×2 的表格為例,表格的行從上到下編號,列從左到右編號。我們將 1 1 1 置于左上角單元格, 2 2 2 置于右下角單元格, 3 3 3 置于左下角單元格, 4 4 4 置于右上角單元格。這就是他所需要的全部樂趣!

幸運的是,瓦迪姆有一個大小為 2 n × 2 n 2^n \times 2^n 2n×2n 的表格。他計劃用從 1 1 1 2 2 n 2^{2n} 22n 的整數按升序填滿它。為了填滿這樣一個大表,瓦迪姆將把它分成 4 4 4 個相等的方表,先填滿左上角的表,然后填滿右下角的表,接著填滿左下角的表,最后填滿右上角的表。在填滿每張小方表的過程中,他又會把每張小方表分割成更小的表,直到填滿 2 × 2 2 \times 2 2×2 大小的方表為止。

現在瓦迪姆迫不及待地想開始填表,但是他有兩類 q q q 個問題:

  • x x x 行第 y y y 列的單元格中的數字是多少
  • 數字 d d d 位于哪個單元格坐標

幫助回答瓦迪姆的問題。

題解思路:DFS

題意倒是很直接,思路也很明確,就是不斷DFS縮小區域。但是這個區域怎么設計還真是惡心,會的很會,不會的真的會卡很久,看群友有被卡兩小時的。

首先對于塊的大小,假如當前處于第 n n n 層,塊的大小為 2 n ? 1 × 2 n ? 1 2^{n - 1} \times 2^{n - 1} 2n?1×2n?1 ,即是寬高各減一半。其次是對于坐標步長,根據前面分析(寬高各減一半),可知步長就是 2 n ? 1 2^{n - 1} 2n?1 。知道這兩個性質就好辦了,只需要知道當前處于第幾層,以及當前層的左上角坐標,即可一步步縮小范圍,直到不能再縮小,即是答案,詳見代碼。時間復雜度為 O ( n q ) O(nq) O(nq)

參考代碼(C++)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
int n, q;ll dfs1(int cur, int l, int r, int x, int y) {// cout << "dfs1:" << cur << ':' << l << ':' << r << ':' << x << ':' << y << '\n';if (l == x && r == y)return 1;ll dt = 1LL << (cur - 1);ll dd = dt * dt;if (x >= l + dt && y >= r + dt)return dd + dfs1(cur - 1, l + dt, r + dt, x, y);if (x >= l + dt)return (dd << 1) + dfs1(cur - 1, l + dt, r, x, y);if (y >= r + dt)return 3 * dd + dfs1(cur - 1, l, r + dt, x, y);return dfs1(cur - 1, l, r, x, y);
}pii dfs2(int cur, int l, int r, ll d) {// cout << "dfs2:" << cur << ':' << l << ':' << r << ':' << d << '\n';if (d == 1)return {l, r};ll dt = 1LL << (cur - 1);ll dd = dt * dt;if (d > 3 * dd)return dfs2(cur - 1, l, r + dt, d - 3 * dd);if (d > (dd << 1))return dfs2(cur - 1, l + dt, r, d - (dd << 1));if (d > dd)return dfs2(cur - 1, l + dt, r + dt, d - dd);return dfs2(cur - 1, l, r, d);
}void solve() {cin >> n >> q;string op;int x, y;ll d;while (q--) {cin >> op;if (op == "->") {cin >> x >> y;cout << dfs1(n, 1, 1, x, y) << '\n';} else {cin >> d;pii ans = dfs2(n, 1, 1, d);cout << ans.first << ' ' << ans.second << '\n';}}
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;cin >> t;while (t--)solve();return 0;
}

Problem E. Min Max MEX

題目大意

給你一個長度為 n n n 的數組 a a a 和一個數字 k k k

子數組的定義是數組中一個或多個連續元素的序列。你需要將數組 a a a 分割成 k k k 個不重疊的子數組 b 1 , b 2 , … , b k b_1, b_2, \dots, b_k b1?,b2?,,bk? ,使得這些子數組的合集等于整個數組。此外,你需要最大化 x x x 的值,即 x = min ? ( M E X ( b i ) ) , 1 ≤ i ≤ k x = \min(MEX(b_i)), 1 \leq i \leq k x=min(MEX(bi?)),1ik

M E X ( v ) MEX(v) MEX(v) 表示數組 v v v 中沒有的最小非負整數。

題解思路:二分

對于 u = M E X ( v ) u = MEX(v) u=MEX(v) ,如果選擇數組 v v v 的一部分數組成數組 v t vt vt ,那么對于所有 w < u w \lt u w<u ,是否都能找到 w = M E X ( v t ) w = MEX(vt) w=MEX(vt) ?答案是肯定的。所以我們考慮二分,下限 l = 0 l = 0 l=0 ,上限 r = n r = n r=n (因為數組頂多是 [ 0 , 1 , … , n ? 1 ] [0, 1, \dots, n - 1] [0,1,,n?1] )。那么我們怎么去check呢?對于 M E X MEX MEX u u u ,我們只需要維護一個集合,然后遍歷整個數組,對于每個元素,滿足 a i < u , 0 ≤ i < n a_i \lt u, 0 \leq i \lt n ai?<u,0i<n ,就將其加入集合,當集合元素個數達到了 u u u ,然后計數加一(表示可以劃分為一個子數組,滿足 M E X ≥ u MEX \geq u MEXu),并且清空當前集合。這樣到最后,只要計數大于等于 k k k ,表示可以合理劃分。時間復雜度為 O ( n l o g n l o g n ) O(nlognlogn) O(nlognlogn) (check用到了set,換成數組每次標記取反可以降到 O ( n l o g n ) O(nlogn) O(nlogn) )。

PS:此題居然卡雙 l o g log log 做法常數,真是無語啊!

參考代碼(C++)

l o g log log 超時代碼。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int maxn = 200'005;
int a[maxn];
int n, m;bool check(int x) {set<int> st;for (int i = 0; i < x; ++i)st.insert(i);if (st.empty())return true;set<int> stc;int cnt = 0;for (int i = 0; i < n; ++i) {if (a[i] < x)stc.insert(a[i]);if (stc.size() == st.size()) {++cnt;stc.clear();if (cnt >= m)return true;}}return cnt >= m;
}void solve() {cin >> n >> m;for (int i = 0; i < n; ++i)cin >> a[i];int l = 0, r = n + 1, ans = -1;while (l <= r) {int mid = (l + r) >> 1;if (check(mid)) {ans = mid;l = mid + 1;} elser = mid - 1;}cout << ans << '\n';
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;cin >> t;while (t--)solve();return 0;
}

l o g log log 通過代碼。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int maxn = 200'005;
int a[maxn];
int n, m;bool check(int x) {set<int> st;int cnt = 0;for (int i = 0; i < n; ++i) {if (a[i] < x)st.insert(a[i]);if (st.size() == x) {++cnt;st.clear();if (cnt >= m)return true;}}return cnt >= m;
}void solve() {cin >> n >> m;for (int i = 0; i < n; ++i)cin >> a[i];int l = 1, r = n, ans = 0;while (l <= r) {int mid = (l + r) >> 1;if (check(mid)) {ans = mid;l = mid + 1;} elser = mid - 1;}cout << ans << '\n';
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;cin >> t;while (t--)solve();return 0;
}

l o g log log 通過代碼。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int maxn = 200'005;
int a[maxn];
bool vis[maxn];
int n, m;bool check(int x) {for (int i = 0; i < x; ++i)vis[i] = false;bool f = true;int cnt = 0, cur = 0;for (int i = 0; i < n; ++i) {if (a[i] < x) {if (vis[a[i]] != f) {++cur;vis[a[i]] = f;}}if (cur == x) {++cnt;cur = 0;f = !f;if (cnt >= m)return true;}}return cnt >= m;
}void solve() {cin >> n >> m;for (int i = 0; i < n; ++i)cin >> a[i];int l = 1, r = n, ans = 0;while (l <= r) {int mid = (l + r) >> 1;if (check(mid)) {ans = mid;l = mid + 1;} elser = mid - 1;}cout << ans << '\n';
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;cin >> t;while (t--)solve();return 0;
}

Problem F. Hackers and Neural Networks

題目大意

黑客們再次試圖利用神經網絡的輸出創建娛樂短語。這一次,他們想獲得長度為 n n n 的字符串數組 a a a

最初,他們有一個長度為 n n n 的數組 c c c ,其中充滿了空白,用符號 ? * ? 表示。因此,如果 n = 4 n = 4 n=4 ,則初始值為 c = [ ? , ? , ? , ? ] c=[*, *, *, *] c=[?,?,?,?]

黑客可以訪問 m m m 個神經網絡,每個神經網絡都有自己的請求答案版本–長度為 n n n 的字符串數組 b i b_i bi?

黑客試圖通過以下操作從數組 c c c 中獲取數組 a a a

  • 選擇神經網絡 i i i ,對數組 c c c 執行下一步操作:選擇一個隨機空白,例如在位置 j j j 處,將 c j c_j cj? 替換為 b i , j b_{i, j} bi,j?

    例如,如果選擇了第一個神經網絡 b 1 = [ ?I? , ?love? , ?apples? ] b_1 = [\text{?I?}, \text{?love?}, \text{?apples?}] b1?=[?I?,?love?,?apples?] ,當前 c = [ ? , ?like? , ? ] c = [*, \text{?like?}, *] c=[?,?like?,?] ,那么在對第一個神經網絡進行操作后, c c c 可能會變成 [ ?I? , ?like? , ? ] [\text{?I?}, \text{?like?}, *] [?I?,?like?,?] [ ? , ?like? , ?apples? ] [*, \text{?like?}, \text{?apples?}] [?,?like?,?apples?]

  • 選擇位置 j j j 并將 c j c_j cj? 替換為空白。

不幸的是,由于黑客訪問神經網絡的方式,他們只能在所有操作完成后才能看到修改后的數組 c c c ,因此他們必須事先指定整個操作序列。

然而,神經網絡的隨機行為可能會導致永遠無法獲得所需的數組,或者獲得所需的數組需要過多的操作。

因此,黑客們希望您能幫助他們選擇一個操作序列,以保證在最少的操作次數內獲得數組 a a a

更具體地說,如果存在一個操作序列可以保證從數組 c c c 中獲得數組 a a a ,那么在所有這樣的序列中,找出一個操作次數最少的序列,并輸出其中的操作次數。

如果沒有將數組 c c c 轉換成數組 a a a 的操作序列,則輸出 ? 1 -1 ?1

題解思路:貪心

題意真的很長且很拉,真的看完好像不知道要求什么?讓我們再細細品味一下!反正就是進行兩個操作嘛,只要對應位置的字符串不對就一定要繼續操作。只要操作,那么操作次數必然會增加。

假如某個操作后,某個位置已經是正確的,下一次操作你會不會去改它?顯然不會了,不然你還得再至少進行一次操作二以及至少隨機一次操作一,而且隨機后不一定是對的,何必呢?

如果所有位置都是空的,你會不會進行操作二?顯然也不會,白白浪費一次操作嘛。所以第一次操作肯定是操作一,這是個隨機過程。

通過上面的分析,我們唯一能決定的就是可以選擇跑哪個神經網絡。從概率論角度來說,我們當然希望選擇命中概率更高的,這樣所得的期望就越大,后續所需要的操作就更少。所以第一次操作就至關重要了,我們就選命中概率最大的神經網絡,這樣我們就能保證 n n n 次操作后,隨機正確位置最大。這樣所有位置都被填滿了,最后對不正確的位置,我們只需要先執行一次操作二,再找到一個神經網絡,其對應位置存在正確字符串,因為只會空白位置隨機,而當前空白位置只有一個,顯然這是一個必然事件。

上面操作一定是最優的嗎?一定的。假設你選擇某個神經網絡的命中率是 x y \frac{x}{y} yx? ,你把其他所有的神經網絡全部組合起來,命中率形如 x + a y + b \frac{x + a}{y + b} y+bx+a? ,其不可能更大。

對于不存在的情況,顯然所有對應位置都沒有目標串,就無法做到。時間復雜度為 O ( m n max ? ( ∣ b i , j ∣ ) ) O(mn \max(|b_{i, j}|)) O(mnmax(bi,j?))

參考代碼(C++)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int maxn = 505;
string p[maxn], str[maxn][maxn];
int cntr[maxn], cntc[maxn];
int n, m;void solve() {cin >> n >> m;for (int i = 0; i < n; ++i) {cin >> p[i];cntc[i] = 0;}for (int i = 0; i < m; ++i) {cntr[i] = 0;for  (int j = 0; j < n; ++j) {cin >> str[i][j];if (str[i][j] == p[j]) {++cntc[j];++cntr[i];}}}for (int i = 0; i < n; ++i)if (cntc[i] == 0) {cout << "-1\n";return;}int maxc = 0;for (int i = 0; i < m; ++i)maxc = max(maxc, cntr[i]);cout << (n + ((n - maxc) << 1)) << '\n';
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;cin >> t;while (t--)solve();return 0;
}

Problem G. Shorten the Array

題目大意

長度為 m m m 的數組 b b b 的美感定義為所有可能數對 1 ≤ i ≤ j ≤ m 1 \leq i \leq j \leq m 1ijm 中的 max ? ( b i ⊕ b j ) \max(b_i \oplus b_j) max(bi?bj?) ,其中 x ⊕ y x \oplus y xy 是數字 x x x y y y 的 bitwise XOR。我們將數組 b b b 的美感表示為 f ( b ) f(b) f(b)

如果數組 b b b 中有 f ( b ) ≥ k f(b) \geq k f(b)k ,那么這個數組 b b b 就叫做美麗數組。

最近,科斯佳從商店買了一個長度為 n n n 的數組 a a a 。他認為這個數組太長了,所以打算從中剪切出一些美麗的子數組。也就是說,他想選擇數字 l l l r r r ( 1 ≤ l ≤ r ≤ n 1 \leq l \leq r \leq n 1lrn ),這樣數組 a l … r a_{l \dots r} alr? 就很美麗了。這樣一個子數組的長度為 r ? l + 1 r - l + 1 r?l+1 。整個數組 a a a 也被視為一個子數組(包含 l = 1 l = 1 l=1 r = n r = n r=n )。

你的任務是找出數組 a a a 中最短的美麗子數組的長度。如果沒有一個子數組是美麗的,那么你應該輸出數字 ? 1 -1 ?1

題解思路:雙指針+字典樹Trie

首先,對于每個 l l l ,如果找到第一個滿足條件的 r ( r ≥ l ) r(r \geq l) r(rl) ,那么顯然 r + 1 ( r < n ) r + 1(r \lt n) r+1(r<n) 也可以。既然這樣,那么我們維護一個雙指針,對于每個左指針,不斷擴展右指針,直到找到第一個滿足條件的位置,更新答案即可。那么怎么快速計算出當前區間是否可以滿足條件呢?很容易就會想到字典樹求當前區間可以得到的最大異或值。時間復雜度為 O ( n ) O(n) O(n) (計算次數實際為 30 n 30n 30n ,常數忽略,但實際運行時間還是要考慮的)。

參考代碼(C++)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int maxn = 200'005;
const int maxnode = 6'000'005;
const int sigma_size = 2;
struct trie {int child[maxnode][sigma_size];int value[maxnode];int size;void init() {size = 1;memset(child[0], 0, sizeof(child[0]));}void insert(int x, int y) {int pos = 0;for (int i = 29; i >= 0; --i) {int id = (x >> i) & 1;if (!child[pos][id]) {memset(child[size], 0, sizeof(child[size]));value[size] = 0;child[pos][id] = size++;}pos = child[pos][id];value[pos] += y;}}int query(int x) {// cout << "query: " << x << '\n';int pos = 0, ans = 0;for (int i = 29; i >= 0; --i) {int id = (x >> i) & 1;int idx = id ^ 1;int p = child[pos][idx];if (p && value[p]) {ans |= 1 << i;pos = p;} else {p = child[pos][id];if (p && value[p])pos = p;elsereturn -1;}}// cout << "query: ans = " << ans << '\n';return ans;}
} tr;
int a[maxn];
int n, m;void solve() {cin >> n >> m;for (int i = 0; i < n; ++i)cin >> a[i];if (m == 0) {cout << "1\n";return;}tr.init();int l = 0, r = 0, ans = n + 1;while (r < n) {// cout << l << ", " << r << endl;while (r < n && tr.query(a[r]) < m)tr.insert(a[r++], 1);if (r < n)ans = min(ans, r - l + 1);tr.insert(a[l++], -1);if (l > r)r = l;}cout << (ans == n + 1 ? -1 : ans) << '\n';
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t = 1;cin >> t;while (t--)solve();return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/76067.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/76067.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/76067.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【python讀取并顯示遙感影像】

在Python中讀取并顯示遙感影像&#xff0c;可以使用rasterio庫讀取影像數據&#xff0c;并結合matplotlib進行可視化。以下是一個完整的示例代碼&#xff1a; import rasterio import matplotlib.pyplot as plt import numpy as np# 打開遙感影像文件 with rasterio.open(path…

怎樣使用Python編寫的Telegram聊天機器人

怎樣使用Python編寫的Telegram聊天機器人 代碼直接運行可用 以下是對這段代碼的詳細解釋: 1. 導入必要的庫 import loggingfrom telegram import Update from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, filters, MessageHandler import log…

moviepy學習使用筆記

目錄 1. moviepy安裝版本選擇安裝命令2. 使用文檔1.0.3文檔中文文檔寫的比較好的學習博客2.x文檔1.0.3到2.x快速上手3. 可能遇到的問題3.1 依賴問題3.2 中文顯示問題4. 特效示例中文顯示的問題1. moviepy安裝 版本選擇 moviepy有兩個主流版本: 1.0.3 和 2.x 目前2.x版本稱不…

docker各種清空緩存命令,下載jdk包總失敗,執行完好了

清理未使用的鏡像&#xff08;推薦&#xff0c;最常用&#xff09;&#xff1a; docker image prune -a 清理所有未使用的數據&#xff08;包括鏡像、容器、網絡和構建緩存&#xff09;&#xff1a; docker system prune -a 清理所有未使用的數據&#xff0c;包括未使用的卷…

NO.78十六屆藍橋杯備戰|數據結構-并查集|雙親表示法|初始化|查詢|合并|判斷|親戚|Lake Counting|程序自動分析(C++)

雙親表?法 接下來要學習到的并查集&#xff0c;本質上就是?雙親表?法實現的森林。因此&#xff0c;我們先認識?下雙親表?法。 在學習樹這個數據結構的時&#xff0c;講到樹的存儲?式有很多種&#xff1a;孩?表?法&#xff0c;雙親表?法、孩?雙親表?法以及孩?兄弟表…

Ubuntu掛載HDD遷移存儲PostgreSQL數據

關聯博客&#xff1a;windows通用網線連接ubuntu實現ssh登錄、桌面控制、文件共享 背景&#xff1a; 在個人ubuntu機器上安裝了pgsql&#xff0c;新建了一張表插入了2000w數據用于模擬大批量數據分頁查詢用&#xff0c;但是發現查詢也不慢&#xff08;在公司測試環境查詢1700…

Spring MVC與Spring Boot文件上傳配置項對比

Spring MVC與Spring Boot文件上傳配置項對比 一、Spring MVC配置項&#xff08;基于不同MultipartResolver實現&#xff09; 1. 使用 CommonsMultipartResolver&#xff08;Apache Commons FileUpload&#xff09; Bean public MultipartResolver multipartResolver() {Common…

Android 學習之 Navigation導航

1. Navigation 介紹 Navigation 組件 是 Android Jetpack 的一部分&#xff0c;用于簡化應用內導航邏輯&#xff0c;支持 Fragment、Activity 和 Compose 之間的跳轉。核心優勢&#xff1a; 單 Activity 架構&#xff1a;減少 Activity 冗余&#xff0c;通過 Fragment 或 Com…

Docker Compose 部署Nginx反向代理 tomcat

Nginx 、Tomcat (默認端口8080)》》compose services:nginx:image: nginx:latestcontainer_name: nginxrestart: alwaysports:- 80:80- 8080:8080volumes:# 文件夾會自動創建&#xff0c;但nginx.conf是文件&#xff0c;需要提前創建&#xff0c;否則 會自動創建nginx.conf文件…

數據庫7(數據定義語句,視圖,索引)

1.數據定義語句 SQL數據定義語言&#xff08;DDL&#xff09;用于定義和管理數據庫結構&#xff0c;包括創建、修改和刪除 數據庫對象。常見的DDL語句包括CREATE、DROP和ALTER。 它的操作的是對象&#xff0c;區分操作數據的語句&#xff1a;INSERT,DELETE,UPDATE 示例&#x…

QML面試筆記--UI設計篇02布局控件

1. QML 中常用的布局控件 1.1. Row1.2. Column1.3. Grid1.4. RowLayout1.5. ColumnLayout1.6. GridLayout1.7. 總結 1. QML 中常用的布局控件 1.1. Row 背景知識&#xff1a;Row 布局用于將子元素水平排列&#xff0c;適合簡單的線性布局&#xff0c;如工具欄按鈕或表單輸入…

Compose組件轉換XML布局1.0

文章目錄 學習JetPack Compose資源前言&#xff1a;預覽界面的實現Compose組件的布局管理一、Row和Colum組件&#xff08;LinearLayout&#xff09;LinearLayout&#xff08;垂直方向 → Column&#xff09;LinearLayout&#xff08;水平方向 → Row&#xff09; 二、相對布局 …

從零構建大語言模型全棧開發指南:第五部分:行業應用與前沿探索-5.2.1模型偏見與安全對齊(Red Teaming實踐)

?? 點擊關注不迷路 ?? 點擊關注不迷路 ?? 點擊關注不迷路 文章大綱 大語言模型全棧開發指南:倫理與未來趨勢 - 第五部分:行業應用與前沿探索5.2.1 模型偏見與安全對齊(Red Teaming實踐)一、模型偏見的來源與影響1. 偏見的定義與分類2. 偏見的實際影響案例二、安全對齊…

java基礎 迭代Iterable接口以及迭代器Iterator

Itera迭代 Iterable < T>迭代接口(1) Iterator iterator()(2) forEach(Consumer<? super T> action)forEach結合Consumer常見場景forEach使用注意細節 (3)Spliterator spliterator() Iterator< T>迭代器接口如何“接收” Iterator<T>核心方法迭代器的…

PyTorch構建自定義模型

PyTorch 提供了靈活的方式來構建自定義神經網絡模型。下面我將詳細介紹從基礎到高級的自定義模型構建方法&#xff0c;包含實際代碼示例和最佳實踐。 一、基礎模型構建 1. 繼承 nn.Module 基類 所有自定義模型都應該繼承 torch.nn.Module 類&#xff0c;并實現兩個基本方法&…

AI智算-K8s如何利用GPFS分布式并行文件存儲加速訓練or推理

文章目錄 GPFS簡介核心特性存儲環境介紹存儲軟件版本客戶端存儲RoCEGPFS 管理(GUI)1. 創建 CSI 用戶2. 檢查GUI與k8s通信文件系統配置1. 開啟配額2. 啟用filesetdf文件系統3. 驗證文件系統配置4. 啟用自動inode擴展存儲集群配置1. 啟用對根文件集(root fileset)配額2. igno…

gbase8s之邏輯導出導入腳本(完美版本)

該腳本dbexport.sh用于快速導出庫和導入庫&#xff08;使用多并發unload&#xff0c;和多并發dbload的方式&#xff09; #!/bin/sh #腳本功能&#xff1a;將數據導出成文本&#xff0c;遷移至其他實例 #最后更新時間&#xff1a;2023-12-19 #使用方法&#xff1a; #1.執行該腳…

springMVC-攔截器詳解

攔截器 概述 SpringMVC的處理器攔截器類似于Servlet開發中的過濾器Filter,用于對處理器進行預處理和后處理。開發者可以自己定義一些攔截器來實現特定的功能。 過濾器與攔截器的區別&#xff1a;攔截器是AOP思想的具體應用。 過濾器 servlet規范中的一部分&#xff0c;任何ja…

網絡安全應急響應-系統排查

在網絡安全應急響應中&#xff0c;系統排查是快速識別潛在威脅的關鍵步驟。以下是針對Windows和Linux系統的系統基本信息排查指南&#xff0c;涵蓋常用命令及注意事項&#xff1a; 一、Windows系統排查 1. 系統信息工具&#xff08;msinfo32.exe&#xff09; 命令執行&#x…

基于YOLO的半自動化標注方法:提升鐵路視頻缺陷檢測效率

論文地址:https://arxiv.org/pdf/2504.01010 1. 論文結構概述 本文提出了一種半自動化標注方法,旨在解決鐵路缺陷檢測中大規模圖像/視頻數據集標注成本高、耗時長的問題。論文結構清晰,分為以下核心部分: ?引言(Introduction)? 強調傳統手動標注的痛點(耗時、易錯、…