Duel 记录

CP Duels

· CF204C Little Elephant and Furik and Rubik

容易求出总的匹配对数,即 \(\sum\limits_{i=1}^ni^2\),要求期望只要求 \(\sum f(x,y)\).

考虑每对匹配的字符对 \(\sum f(x,y)\) 的贡献.

因为一对匹配的字符在字符串中的相对位置不变,所以它的贡献就是能同时延伸到的字符串个数.

不妨设第一个字符的位置为 \(i\),第二个字符的位置为 \(j>i\),那么贡献就是 \(i\times(n-j+1)\).

由于字符集大小 \(\Sigma\) 很小,可以枚举 \(\Sigma\) 的字符和第一个字符的位置,动态维护第二个字符的位置的前缀和与后缀和.

- CF2B The least round way

最小化后缀 \(0\) 个数也就是最小化路径上数的 \(2\)\(5\) 的次数.

考虑分别记录 \(2\)\(5\) 的最小次数,较小值即为后缀 \(0\) 的最小个数.

需要特判 \(0\) 存在的情况.

- CF1254B1 Send Boxes to Alice (Easy Version)

只要考虑非零的 \(a_i\) 为同一质因数的情况.

最小距离就是每段与中位数的距离.

+ CF251C Number Transformation

注意到 \(\mathop{\operatorname{lcm}}\limits_{i=2}^{15} \ i = 360360\) 很小,这意味着可以将数轴划分为长度为 \(\operatorname{lcm}\) 的段,不同段相同位置的行为是相同的.

并且可以发现在同一个段中操作最终总是到 \(\operatorname{lcm}\) 的倍数.

于是可以在段内 dp 跳过前面的段,最后一段 bfs 即可.

· CF1930C Lexicographically Largest

每个 \(a_i\) 能贡献的最大数就是 \(a_i+i\). 考虑证明如果两个数贡献的数相同,一定有一个能减 \(1\) 而其它数不受影响.

对于每一个位置 \(i\),其要减的数可以不超过 \(i\),那么必然可以以一定的顺序通过先操作前面的数得到要减的个数.

+ CF1036C Classy Numbers

\(f(x,d)\) 表示 \(0\sim x\) 中含义不超过 \(d\) 个非零数字的数的个数.

\(B=\lfloor\lg x\rfloor\),那么 \(f(x,d)=f(10^B-1,d)+(\lfloor\frac{x}{10^B}\rfloor-1) f(10^B-1,d-1)+f(x\bmod 10^B,d-1)\).

其中 \(f(10^B-1,d)=\sum\limits_{i=0}^d\binom{B}{i}9^i\).

\(f(r,3)-f(l-1,3)\) 即为所求.

· CF360B Levko and Array

二分答案 \(x\).

\(dp_i\) 表示 \(a_i\) 不改变,前面的数使得答案成立最少需要改变多少次.

转移考虑距离 \(i\) 最近的不改变的位置 \(j\).

那么 \(i\sim j\) 间的所有数都可以改变,使答案成立当且仅当 \(|a_i-a_j|\leq (i-j)x\).

+ CF1887B Time Travel

枚举时刻 \(i\),我们只要知道有多少点可以在时刻 \(i\) 第一次被访问到并把它加到访问到的点的集合里.

因为一条边只会贡献一个点,所以可以尝试枚举边加点.

如果边中两点都没被访问到,那么就会被重复考虑,所以每当新点被访问,我们再加入点对应的边即可.

这样所有边都只会被考虑到一次,使用 std::unordered_map 复杂度是 \(O(k+\sum m_i)\) 的.

· CF1995C Squaring

直接从前往后贪心模拟就好了.

因为如果 \(x<y\),那么 \(x^2<y^2\),所以只要记录平方的次数,再在相邻原项模拟.

· CF474C Captain Marmot

判断 \(4\) 个点是否构成正方形. 计算 \(d=\sum\limits_{(\mathbf x, \mathbf y)} (\mathbf x-\mathbf y)^2\),然后判断有没有 \(6\) 对点的距离平方是 \(\frac{d}{8}\) 或者 \(\frac{d}{4}\).

· CF578C Weakness and Poorness

每个区间 $[l,r] $的 poorness\(P(x)=\lvert\sum\limits_{i=l}^r a_i - (r-l+1)x\rvert\) 两段直线,先减后增.

于是 weakness\(W(x)=\max P(x)\) 就是凸的,用三分检验最大子段和即可.

几何做法再说.

+ CF1918D Blocking Elements

二分答案 \(x\).

然后考虑 dp,令 \(f_i\) 表示前 \(i\) 个数 在满足区间和最值约束下 分隔点和的最值.

转移就是部分和小于等于 \(x\) 的最小 \(f\),可以用 map 维护.

+ CF1969D Shop Game

因为 Bob 总是会选 \(b_i\) 最大的 \(k\) 个,钦定 Bob 选择的最小 \(b_i\).

对于 Bob 选择的 \(k\) 个数,选择 \(\geq b_i\)\(a_i\) 最小的 \(k\) 个,可以大根堆动态维护.

对于其他 \(<b_i\) 的数,使用前缀和计算最大收益就可以了.

· CF1184E1 Daleks' Invasion (easy)

删除第一条边求 MST,当第一条边的两个端点合并至同一联通块时计算答案.

+ CF2036G Library of Magic

如果返回的答案不为 \(0\),二分即可找到答案.

不过如果 \(a \oplus b = c\),并且询问的区间同时包含这三个数就会返回 \(0\).

怎么样避免区间同时包含这三个数呢?注意到如果 \(a \oplus b = c\),那么肯定存在一个数 \(1\) 的最高位比其他两个数低.

进一步地,如果 \(a\oplus b = c\),那么 \(2\min(a,b,c) < \max(a,b,c)\).

于是如果询问区间长度等于左端点,必然不会出现包含要找的数且返回 \(0\) 的情况.

我们可以先询问全局异或和,这样就只要找到两个数了.

然后每次询问 \([2^i,2^{i+1})\),如果询问答案 \(x\) 不为 \(0\) 可以二分找到一个数 \(y\),如果 \(x \neq y\) 可以通过消除 \(y\) 的影响再二分找到第二个数.

询问次数是 \(3\log_2 x\),注意到 \(\log_2 10^{18} \approx 60\),最大询问次数 \(150\) 也就是 \(2.5\log_2 N\),直接这样问是会 WA 的.

再怎么减少询问次数呢,考虑从大到小询问 \([2^i,2^{i+1})\). 那样询问的最大次数就变成了 \(\log_2N + \log_2x\),足够通过本题.

还有另一种思考方式,因为 \(a\oplus b \neq c\) 的时候可以二分,所以只要考虑相等的情形,其中两个较大的数 \(1\) 最高位一定相同.

于是可以从高到低查找它们的最高位在哪里. 找到之后,二分就可以了.

然后发现 \(a \oplus b \neq c\) 的时候也可以通过这种做法找到两个较大数的最高位,所以最后的实现和第一种思考方式居然是一模一样的!

+ CF431D Random Task

因为 \(n\)\(2n\) 二进制 \(1\) 的个数相同,所以答案是递增的,且每次最多加一,那么必然有解.

考虑二分,计算 \(f(n,k)\)\(0\sim n\) 的数中恰有 \(k\)\(1\) 的个数.

\(B=\lfloor\log_2n\rfloor\),将 \([0,n]\) 拆成 \([0,2^B)\cup [2^B,2^B+(n-2^B)]\),那么 \(f(n,k)=\binom{B}{k}+f(n-2^B,k-1)\).

因为 \(\binom{64}{32}\approx 1.8\times10^{18}\),所以可以直接递推求组合数(当然也可以用 long double 或者用 __int128 在模大质数意义下求组合数).

- CF551B ZgukistringZ

转化为 \(\max\limits_{k=0}^{n}(\min\limits_{i=1}^\Sigma (A_i-kBi)/C_i+k)\).

因为字符集大小 \(\Sigma=26\),直接 \(O(n\Sigma)\) 枚举即可.

posted @ 2024-12-10 22:31  Lcyanstars  阅读(13)  评论(1编辑  收藏  举报