题解
A
显然,如果数组不是全 $0$,就一定可以变成 $\left[1\right]$。
B
考虑最优情况一定是 $000...0 111...1$,所以要把数组里的 $1$ 都调到最后面。具体实现方法是遍历数组,一共有 $cnt$ 个 $1$,接着遍历数组的最后 $cnt$ 个元素,一共有 $k$ 个 $0$,则需要 $k$ 次操作。
C
如果 $a_i > a_{i + 1}$,则需要 $a_i - a_{i + 1}$ 后缀加 $i$ 使得 $a_{i + 1} = a_i$,所以我们使用一个 vector
来记录所有的可用操作,每次在 vector
里 lower_bound
一个大于等于 $a_i - a_{i + 1}$ 的操作来用,然后从 vector
里删除。这样是 $\mathcal O\left(n \sqrt n\right)$ 的,我同学用这个方法过了,但是我常数写大了一丢丢,System Test 的时候 TLE 了。。。
我猜测 vector
是通过打死亡标记 + 定期重构实现根号删除的。
UPD:vector
只是常数小而已,可能用了一些指令集之类的东西,但不是根号的。
显然,可用使用平衡树优化至 $\mathcal O\left(n \log n\right)$。
D
暂时鸽了。
E1
赛时想的是把序列平分成 $3$ 段,结果发现不行,原来分成 $4$ 段就行了啊啊啊啊啊。。。。
我们把 $s$ 平分成 $4$ 份,$s_1, s_2, s_3$ 和 $s_4$。然后询问 $\left\{s_1 \cup s_2\right\}$ 和 $\left\{s_1 \cup s_3\right\}$。
然后,我们分类讨论:
- 返回
N, N
,发现 $x$ 一定不在 $s_1$ 里。 - 返回
N, Y
,发现 $x$ 一定不在 $s_2$ 里。 - 返回
Y, N
,发现 $x$ 一定不在 $s_3$ 里。 - 返回
Y, Y
,发现 $x$ 一定不在 $s_4$ 里。
一直重复这个操作知道 $s$ 里的元素个数小于等于 $4$。
这样 $s$ 的大小每次会变成原来的 $\dfrac34$,通过计算发现最多通过 $76$ 次询问可以缩小至 $s$ 的大小到 $4$,然后暴力询问 $4$ 次,确定最终答案。题目给了 $82$ 次询问,绰绰有余。
E2
不会。
F
乱搞。
首先,离散化,给每个取值都随机一个值,然后我们在把一段区间里的权值加起来,得到 $h_{l, r}$,则如果一个区间里的每个数的出现次数都是 $k$ 的倍数,则 $h_{l, r}$ 也必然是 $k$ 的倍数。反之可能不是。所以,当 $k = 2$ 时,有 $\dfrac12$ 的概率检测错误,但是如果我们对于每个数使用 $p$ 个同的随机值,这样对于 $k = 2$ 检测错误的概率就是 $\dfrac1{2^p}$。使用树状数组或线段树维护 $h_{l, r}$。
G
不会。
代码
F
// Please submit with C++14! It's best to use C++20 or higher version. constexpr bool __MTCS__ = 0; // Spectre (n@rbtr.ee) #ifndef LOCAL // By rbtree (https://rbtr.ee) #pragma region HEAD // DO OR DIE #endif #include <algorithm> #include <array> #include <bitset> #include <cmath> #include <cstring> #include <functional> #include <iostream> #include <list> #include <map> #include <numeric> #include <queue> #include <random> #include <set> #include <unordered_map> #include <utility> #include <vector> #ifdef ___RB_DEBUG___ #include "rb_debug.h" #else #define dbg(...) #endif #define ra (scanf("%lld", &la), la) #define se(exp) exp.begin(), exp.end() #define LIKELY(exp) __builtin_expect(bool(exp), 1) #define UNLIKELY(exp) __builtin_expect(bool(exp), 0) typedef long long tp; using namespace std; void __Cored__(tp); tp la; signed main(/* >_< */) { for (static tp __TCS__ = __MTCS__ ? ra : 1, __NOW__ = 0; __NOW__ < __TCS__; __Cored__(++__NOW__)) { } return 0; } #ifndef LOCAL #pragma endregion HEAD #endif //////////////////////////////////////////////////////////////////////////////// constexpr tp c_P = 33, c_N = 3e5 + 3, c_LIM = 1e9 + 7; tp a[c_N]; unordered_map<tp, tp> xid; tp t[c_P][c_N]; tp c[c_P][c_N * 2]; void modify(tp x, tp y, tp k) { while (y < c_N) { t[x][y] += k; y += y & -y; } } tp query(tp x, tp y) { tp tar = 0; while (y) { tar += t[x][y]; y -= y & -y; } return tar; } void __Cored__([[maybe_unused]] tp __TID__) { tp n = ra, m = ra; mt19937 rnd(__builtin_ia32_rdtsc() % c_LIM); for (tp i = 1; i <= n; ++i) { a[i] = ra; if (!xid[la]) { xid[la] = xid.size() + 1; for (tp j = 0; j < c_P; ++j) c[j][xid[la]] = rnd(); } for (tp j = 0; j < c_P; ++j) modify(j, i, c[j][xid[la]]); } while (m--) { if (ra == 1) { tp i = ra, x = ra; if (!xid[x]) { xid[x] = xid.size() + 1; for (tp j = 0; j < c_P; ++j) c[j][xid[x]] = rnd(); } for (tp j = 0; j < c_P; ++j) modify(j, i, c[j][xid[x]] - c[j][xid[a[i]]]); a[i] = x; } else { bool f = 1; tp l = ra - 1, r = ra, k = ra; for (tp j = 0; j < c_P; ++j) { if ((query(j, r) - query(j, l)) % k) { f = 0; break; } } puts(f ? "YES" : "NO"); } } } //*/