【比赛链接】
【题解链接】
**【A】**Elevator or Stairs?
【思路要点】
- 按照题意计算两种方式的用时,取较优的方案采纳。
- 时间复杂度 O ( 1 ) O(1) O(1) 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e5 + 5; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int main() { int x, y, z, t1, t2, t3; read(x), read(y), read(z), read(t1), read(t2), read(t3); int s = abs(x - y) * t1; int e = abs(x - z) * t2 + abs(x - y) * t2 + t3 * 3; if (e <= s) printf("YES\n"); else printf("NO\n"); return 0; }
**【B】**Appending Mex
【思路要点】
- 显然在操作合法的情况下,序列中的数形成的集合是一个仅包含最小的 x x x 个自然数的集合,因此,可能加入的数应当是 0 0 0 到 x x x 中的一个整数,按照此判断标准检验操作序列的合法性即可。
- 时间复杂度 O ( N ) O(N) O(N) 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e5 + 5; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int main() { int n, Max = -1; read(n); for (int i = 1; i <= n; i++) { int x; read(x); if (x > Max + 1) { printf("%d\n", i); return 0; } chkmax(Max, x); } printf("-1\n"); return 0; }
**【C】**Candies Distribution
【思路要点】
- 计算 a l l i = l i + r i all_i=l_i+r_i alli=li+ri , a l l i all_i alli 表示大于 a i a_i ai 的数的个数。
- 因此,实际上所有 a i a_i ai 的大小关系已经确定了,我们根据 a l l i all_i alli 构造出一组符合条件的 a i a_i ai ,再检验其是否满足 l i l_i li 和 r i r_i ri 的限制即可。
- 时间复杂度 O ( N 2 ) O(N^2) O(N2) 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e5 + 5; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n, a[MAXN], l[MAXN], r[MAXN]; int rnk[MAXN], pos[MAXN]; bool cmp(int x, int y) { return l[x] + r[x] < l[y] + r[y]; } int main() { read(n); for (int i = 1; i <= n; i++) read(l[i]); for (int i = 1; i <= n; i++) read(r[i]); for (int i = 1; i <= n; i++) pos[i] = i; sort(pos + 1, pos + n + 1, cmp); for (int i = 1; i <= n; i++) { int now = pos[i], last = pos[i - 1]; if (i == 1 || l[now] + r[now] != l[last] + r[last]) rnk[i] = i; else rnk[i] = rnk[i - 1]; a[now] = n - rnk[i] + 1; } for (int i = 1; i <= n; i++) { int cnt = 0; for (int j = 1; j <= i - 1; j++) if (a[j] > a[i]) cnt++; if (cnt != l[i]) { printf("NO\n"); return 0; } cnt = 0; for (int j = i + 1; j <= n; j++) if (a[j] > a[i]) cnt++; if (cnt != r[i]) { printf("NO\n"); return 0; } } printf("YES\n"); for (int i = 1; i <= n; i++) printf("%d ", a[i]); return 0; }
**【D】**Changing Array
【思路要点】
- 令 s i s_i si 为 a i a_i ai 的前缀异或和,一个区间 [ l , r ] [l,r] [l,r] 的区间异或和即为 s r ⊕ s l − 1 s_r\oplus s_{l-1} sr⊕sl−1 ,区间 [ l , r ] [l,r] [l,r] 的区间异或和为 0 0 0 当且仅当 s r = s l − 1 s_r=s_{l-1} sr=sl−1 。
- 题目中对一个数 a i a_i ai 进行取反操作相当于执行 a i = a i ⊕ ( 2 k − 1 ) a_i=a_i\oplus (2^k-1) ai