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 n≥k ) 都可以表示为一个长度正好为 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=a1n−1个 0⋯0a2n−1个 0⋯0…ak ,其中 a i = 1 , 1 ≤ i ≤ k a_i = 1, 1 \leq i \leq k ai=1,1≤i≤k 。那么只要 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)),1≤i≤k 。
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,0≤i<n ,就将其加入集合,当集合元素个数达到了 u u u ,然后计数加一(表示可以划分为一个子数组,满足 M E X ≥ u MEX \geq u MEX≥u),并且清空当前集合。这样到最后,只要计数大于等于 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 1≤i≤j≤m 中的 max ( b i ⊕ b j ) \max(b_i \oplus b_j) max(bi⊕bj) ,其中 x ⊕ y x \oplus y x⊕y 是数字 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 1≤l≤r≤n ),这样数组 a l … r a_{l \dots r} al…r 就很美丽了。这样一个子数组的长度为 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(r≥l) ,那么显然 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;
}
相关文章:
Codeforces Round 1016 (Div. 3)题解
题目地址 https://codeforces.com/contest/2093 锐评 在所有题意都理解正确的情况下,整体难度不算太难。但是偏偏存在F这么恶心的题意,样例都不带解释一下的,根本看不懂题。D题也恶心,在于递归过程的拆分,需要点数学…...
安全理念和安全产品发展史
从安全理念的发展历史来看,技术与产品的演进始终围绕 “威胁对抗” 与 “业务适配” 两大核心展开。以下从七个关键阶段解析安全技术与产品的发展脉络,并结合最新实践与未来趋势提供深度洞察: 一、密码学奠基阶段(1970s 前) 安全理念:以 “信息保密” 为核心,防御手段…...
【深度学习】Downstream Model:预训练模型的下游应用与微调技术
Downstream Model:预训练模型的下游应用与微调技术 文章目录 Downstream Model:预训练模型的下游应用与微调技术1 什么是Downstream Model(下游模型)2 预训练模型与下游任务的关系3 微调技术与迁移学习微调的必要性高效迁移学习参…...
每日算法-250409
这是我今天的算法学习记录。 2187. 完成旅途的最少时间 题目描述 思路 二分查找 解题过程 为什么可以使用二分查找? 问题的关键在于寻找一个最小的时间 t,使得在时间 t 内所有公交车完成的总旅途次数 sum 大于等于 totalTrips。 我们可以观察到时间的单…...
【CSS 选择器组合规则详解】
基础选择器组合 空格:后代选择器 > 直接子元素选择器 . 类选择器 : 伪类选择器 多类选择器 .class1.class2 :多类组合 .class1 .class2 :类的所有后代 .class1 > .class2 :类的子元素特殊选择器 :nth-child() :nth-of-…...
手机静态ip地址怎么获取?方法与解析
而在某些特定情境下,我们可能需要为手机设置一个静态IP地址。本文将详细介绍手机静态IP地址详解及获取方法 一、什么是静态IP地址? 静态IP:由用户手动设置的固定IP地址,不会因网络重启或设备重连而改变。 动态IP:由路…...
NumPy对二维矩阵中的每个元素进行加减乘除和对数运算
使用NumPy对二维矩阵中的每个元素进行加减乘除和对数运算的方法如下: 1. 加减乘除运算 对每个元素进行标量运算,可直接使用算术运算符。 示例代码: import numpy as nparr np.array([[1, 2], [3, 4]])# 加法 result_add arr 5 print(&…...
基于C8051F340单片机的精确定时1S的C程序
一、前言 C8051F340单片的定时器2 是一个 16 位的计数器/定时器,由两个 8 位的 SFR 组成:TMR2L(低字节)和TMR2H(高字节)。定时器 2 可以工作在 16 位自动重装载方式、8 位自动重装载方式(两个 …...
提升Windows安全的一些措施
由简单到复杂,仅供参考 一、杀毒软件: 1、杀毒能力: https://haokan.hao123.com/v?vid3883775443252827335&pdhaokan_share 2、使用注意: 一台主机只安装一个杀毒软件就可以了 杀毒软件会误报,造成正常文件…...
中科岩创基坑自动化监测解决方案
1.行业现状 城市基坑开挖具有施工风险高、施工难度大等特点。由于地下土体性质、荷载条件、施工环境的复杂性,单根据地质勘察资料和室内土工试验参数来确定设计和施工方案,往往含有许多不确定因素,对在施工过程中引发的土体性状、环境、邻近建…...
Elasticsearch 系列专题 - 第二篇:数据建模与索引管理
在掌握了 Elasticsearch 的基本概念和操作后,本篇将重点介绍如何设计和管理索引,以及如何高效地导入和维护数据。这对于构建一个高效、可扩展的搜索系统至关重要。 1. 索引设计 1.1 如何选择合适的索引结构 索引是 Elasticsearch 的核心,设计时需考虑以下因素: 数据用途:…...
解决缓存穿透的布隆过滤器与布谷鸟过滤器:谁更适合你的应用场景?
目录 一、布隆过滤器:高效的空间节省者 1.1 布隆过滤器是什么? 1.2 工作原理 1.3 优点 1.4 缺点 1.5 适用场景 二、布谷鸟过滤器:解决删除难题的创新者 2.1 布谷鸟过滤器是什么? 2.2 工作原理 2.3 优点 2.4 缺点 2.5 适用场景 三、…...
OpenHarmony子系统开发 - 调测工具(一)
OpenHarmony子系统开发 - 调测工具(一) 一、bytrace使用指导 简介 bytrace是开发人员用于追踪进程轨迹、分析性能的一种工具,主要对内核ftrace进行了封装和扩展,来支持用户态的打点。通过该工具可以打开想要查看的用户态和内核l…...
Qt中的鼠标事件
1.鼠标进入事件和鼠标离开事件 1.1添加新文件 1.2ui界面 拖出一个Label控件,修改frameShape为Box,使边框更明显 1.3代码实现 #ifndef MYLABEL_H #define MYLABEL_H#include <QLabel>class myLabel : public QLabel {Q_OBJECT public:explicit m…...
MySQL JOIN详解:INNER JOIN与LEFT JOIN的选择与应用
在数据库查询中,JOIN操作是最常用也最重要的操作之一。不同的JOIN类型会导致完全不同的查询结果,正确选择JOIN类型是编写高效、准确SQL查询的关键。本文将深入探讨INNER JOIN和LEFT JOIN的区别、应用场景以及常见问题。 一、JOIN基础概念 1. 什么是JOI…...
Flink 反压下的 TCP 流控制
1. 什么是 Flink 反压和 TCP 流控制? 反压(Backpressure)是什么? 反压是分布式流处理系统中一种自我调节机制。当下游处理数据的速度跟不上上游发送数据的速度时,反压会让上游放慢发送速度,以避免系统过载…...
山东大学软件学院项目实训开发日志(7)之测试前后端本地部署
基于队长搭建的springbootvue框架,在本地进行测试搭建。 在运行后端过程中,出现下图错误: 查找后发现这个问题出现在 Maven 项目的 pom.xml 文件中,显示找不到一些依赖项。所以在此进行最简单的重新加载项目得以解决,…...
YOLOv11训练中精准率召回率与mAP@0.5的动态变化分析
目标检测模型的训练过程涉及多个关键性能指标和损失函数的变化,这些数据能够直观反映模型的收敛速度、最终精度以及改进效果。本文旨在通过绘制YOLOv11模型在训练过程中的精准率(Precision)、召回率(Recall)、mAP0.5 、…...
Windows下ElasticSearch8.x的安装步骤
下载ElasticSearch:https://www.elastic.co/downloads/elasticsearch (我下载的是目前最新版8.17.4)解压ElasticSearch 进入到ElasticSearch的bin目录下双击elasticsearch.bat 弹出控制台并开始执行,在这一步会输出初始账号和密码…...
Leetcode hot100 (day 8,9)
爬楼梯 做法一:小斐波那契数列,只要注意记忆化递归即可 class Solution { public:int dp[50];int climbStairs(int n) {if(dp[n])return dp[n];if(n2){return dp[2]2;}if(n1){return dp[1]1;}//if(dp[n])return dp[n];return dp[n]climbStairs(n-1)clim…...
LinuxSocket套接字编程
1.介绍函数使用 1.创建套接字 int socket(int domain, int type, int protocol); domain:指定协议族,如AF_INET(IPv4)或AF_INET6(IPv6)。 type:指定套接字类型,如SOCK_DGRAM&#…...
青少年编程考试 CCF GESP Python五级认证真题 2025年3月
Python 五级 2025 年 03 月 题号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 答案 A A A B D B A D A D C A A D B 1 单选题(每题 2 分,共 30 分) 第 1 题 链表不具备的特点是( )。 A. 可随机访问任何一个元素 B. 插入、删除操作不需要移动元素 C…...
Java-对比两组对象找出发生变化的字段工具-支持枚举映射-支持时间-支持显示对应字段中文描述-嵌套list等场景
实体字段比较器(对比两组对象找出发生变化的字段工具类开发) 支持枚举映射 支持时间 支持显示对应字段中文描述 支持嵌套list等场景 下载地址: Java-对比两组对象找出发生变化的字段工具-支持枚举映射-支持时间-支持显示对应字段中文描述-嵌…...
电影舆情分析可视化平台管理端实现
电影舆情分析可视化平台管理端实现 系统概述 本系统的用户主要有三类,游客、普通用户以及电影从业人员。 面向游客和普通用户的是电影网站,系统提供一个便捷的平台,供普通用户搜索和了解电影的基本信息,支持电影预告片播放&…...
【Linux】进程信号(下)
在上一篇中,我们详细探讨了信号的预备知识和产生方式(如硬件异常、终端输入、kill命令、系统调用等)及其背后的操作系统行为。信号作为进程间异步通信的核心机制,其生命周期远不止“产生”这一环节——信号的保存与处理才是实现可…...
华为数字芯片机考2025合集2已校正
单选 1. 题目内容 关于亚稳态的描述错误的是( )。 1. 解题步骤 1.1 理解亚稳态(Metastability)的核心特性 亚稳态是指触发器无法在指定时间内稳定输出有效逻辑电平(0或1)的状态,其关键特点…...
【大模型微调】如何解决llamaFactory微调效果与vllm部署效果不一致如何解决
以下个人没整理太全 一、生成式语言模型的对话模板介绍 使用Qwen/Qwen1.5-0.5B-Chat训练 对话模板不一样。回答的内容就会不一样。 我们可以看到例如qwen模型的tokenizer_config.json文件,就可以看到对话模板,一般同系列的模型,模板基本都…...
基于视觉语言模型的机器人实时探索系统!ClipRover:移动机器人零样本视觉语言探索和目标发现
作者:Yuxuan Zhang 1 ^{1} 1, Adnan Abdullah 2 ^{2} 2, Sanjeev J. Koppal 3 ^{3} 3, and Md Jahidul Islam 4 ^{4} 4单位: 2 , 4 ^{2,4} 2,4佛罗里达大学电气与计算机工程系RoboPI实验室, 1 , 3 ^{1,3} 1,3佛罗里达大学电气与计算机工程系F…...
Java常用工具算法-6--秘钥托管云服务AWS KMS
前言: 之前我们介绍了一些常用的加密算法(如:对称加密AES,非对称加密RSA,ECC等),不论是哪一种都需要涉及到秘钥的管理。通常的做法都是把秘钥放到配置文件中进行配置,但是对于一些高…...
Shell脚本的学习
编写脚本文件 定义以开头:#!/bin/bash #!用来声明脚本由什么shell解释,否则使用默认shel 第一步:编写脚本文件 #!/bin/bash #注释 echo "这是输出" 第二步:加上执行权限:chmod x 脚本文件名.sh 第三步&…...
Java——pdf增加水印
文章目录 前言方式一 itextpdf项目依赖引入编写PDF添加水印工具类测试效果展示 方式二 pdfbox依赖引入编写实现类效果展示 扩展1、将inputstream流信息添加水印并导出zip2、部署出现找不到指定字体文件 资料参考 前言 近期为了知识库文件导出,文件数据安全处理&…...
Redis过期key处理、内存淘汰策略与缓存一致性策略实践方案
在现代的高性能应用开发中,Redis作为一款极为热门的内存数据库,其快速的读写性能和丰富的数据结构使其在缓存、消息队列等诸多领域得到了广泛应用。然而,在实际使用过程中,处理好Redis过期key、选择合适的内存淘汰策略以及确保缓存…...
深入 C++ 线程库:从创建到同步的探索之旅
C在<thread>中定义了C线程库. 创建多线程 #include <iostream> #include <thread> using namespace std; void show(int id, int count) { //线程函数for (int i 0; i < count; i) {cout << "id:" << id << ",值:&qu…...
LangChain使用大语言模型构建强大的应用程序
LangChain简介 LangChain是一个强大的框架,旨在帮助开发人员使用语言模型构建端到端的应用程序。它提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互ÿ…...
程序化广告行业(72/89):Tag Manager系统代码操作与行业发展剖析
程序化广告行业(72/89):Tag Manager系统代码操作与行业发展剖析 大家好!在技术领域不断探索的过程中,我深刻体会到知识共享的重要性。写这篇博客,就是希望能和大家一起深入了解程序化广告行业,…...
数据结构实验3.3:求解迷宫路径问题
文章目录 一,问题描述二,基本要求三,算法分析(一)整体思路(二)详细步骤1. 输入迷宫大小并生成迷宫2. 定义走步规则3. 深度优先搜索(DFS)4. 输出结果 (三&…...
基于SpringBoot的线上历史馆藏系统【附源码】
基于SpringBoot的线上历史馆藏系统(源码L文说明文档) 4 系统设计 系统在设计的过程中,必然要遵循一定的原则才可以,胡乱设计是不可取的。首先用户在使用过程中,能够直观感受到功能操作的便利性,符合…...
Mybatis的springboot项目使用
删除数据 & 占位符 一般常用占位符进行数据库操作,也就是预编译sql。 在UserMapper中定义删除接口 /** 根据id删除用户*/ Delete("delete from user where id #{id}") void deleteById(Integer id);若想要获取返回值,声明为Integer (s…...
网站集群批量管理-Ansible剧本与变量
复盘内容:链接指北 查看ansible命令文档 ansible-doc -s systemd一、剧本 何为剧本: playbook 文件,用于长久保存并且实现批量管理,维护,部署的文件. 类似于脚本存放命令和变量 剧本yaml格式,yaml格式的文件:空格,冒号. 剧本未来我们批量管理,运维必会的内容. …...
HOW - React Developer Tools 调试器
目录 React Developer Tools使用Components 功能特性1. 查看和编辑 props/state/hooks2. 查找组件3. 检查组件树4. 打印组件信息5. 检查子组件 Profiler 功能特性Commit ChartFlame Chart 火焰图Ranked Chart 排名图 why-did-you-render 参考文档: React调试利器&a…...
Spring Cloud Alibaba微服务治理实战:Nacos+Sentinel深度解析
一、引言 在微服务架构中,服务发现、配置管理、流量控制是保障系统稳定性的核心问题。Spring Cloud Netflix 生态曾主导微服务解决方案,但其部分组件(如 Eureka、Hystrix)已进入维护模式。 Spring Cloud Alibaba 凭借 高性能、轻…...
《AI换脸时代的攻防暗战:从技术滥用走向可信未来》
技术迭代图谱 过去五年里,Deepfake技术经历了飞速迭代,从最初的萌芽到如今的广泛应用和对抗措施形成。2017年前后,利用深度学习进行人脸换装的技术首次在社区中出现。一位Reddit网友昵称“deepfakes”,将名人面孔替换到色情影片上…...
25/4/9 算法笔记 DBGAN+强化学习+迁移学习实现青光眼图像去模糊1
整体实验介绍 实验主要是结合DBGAN对抗网络强化学习增强迁移学习增强实现青光眼图像去模糊。今天则是先完成了DBGAN板块模型的训练。 实验背景介绍 青光眼的主要特征有: 视盘形态与杯盘比CDR:青光眼患者主要表现为视杯扩大,盘沿变窄。 视…...
【Claude AI大语言模型连接Blender生成资产】Windows安装Blender MCP教程
前言 最近在学习资产制作,了解到了个好玩的东西,利用AI一步一步搭建资产: 上面这副图就是利用Claude AI调用Blender的Python接口一步一步实现的,挺丑但好玩。 安装教程 进入Github: Blender-MCP 网站,下载该项目&a…...
JSP运行环境安装及常用HTML标记使用
制作一个静态网站的基本页面index.html 实验代码:<form> <label for"username">用户名:</label> <input type"text" id"username" name"username"><br> <label for"password&…...
Git 的进阶功能和技巧
1、分支的概念和使用 1.1、什么是分支? 分支(Branch)是在版本控制中非常重要的概念。几乎所有版本控制系统都支持某种形式的分支。在 Git 中,分支是 Git 强大功能之一,它允许我们从主开发线分离出来,在不…...
WSL1升级到WSL2注意事项
今天要在WSL上安装docker,因为机器上安装了wsl1,docker安装后启动不了,通过询问deepseek发现docker只能在wsl2上安装,因此就想着将本机的wsl1升级到wsl2。 确保你的 Windows 系统是 Windows 10(版本 1903 及以上&…...
392. 判断子序列
https://leetcode.cn/problems/is-subsequence/?envTypestudy-plan-v2&envIdtop-interview-150因为是子序列我们只要关心后一个字符在前一个字符后面出现过就行,至于在哪出现出现几次我们不关心,所以我们可以用HashMap<Character, ArrayList<…...
在 VMware 中为 Ubuntu 24.04 虚拟机设置共享文件夹后,在虚拟机中未能看到共享的内容
在 VMware 中为 Ubuntu 24.04 虚拟机设置共享文件夹后,如果在虚拟机中未能看到共享的内容,可能是由于以下原因: VMware Tools 未正确安装:共享文件夹功能依赖于 VMware Tools 或 Open VM Tools。如果未安装或安装不完整࿰…...
台式电脑插入耳机没有声音或麦克风不管用
目录 一、如何确定插孔对应功能1.常见音频插孔颜色及功能2.如何确认电脑插孔?3.常见问题二、 解决方案1. 检查耳机连接和设备选择2. 检查音量设置和静音状态3. 更新或重新安装声卡驱动4. 检查默认音频格式5. 禁用音频增强功能6. 排查硬件问题7. 检查系统服务8. BIOS设置(可选…...