Codeforces Global Round 29 (Div. 1 + Div. 2)
Codeforces Global Round 29 (Div. 1 + Div. 2)
A. Shortest Increasing Path
因为 \(x,y\ge1\),所以如果 \(x=y\) 一定无解,且不存在可以一步到达的点。
如果一个位置可以通过 \(k>3\) 步到达,最后两步一定可以合并到前面,从而使用 \(k-2\) 步到达。
考虑进行两次操作和三次操作分别可以到达那些点。容易发现二次操作可以到达所有 \(x<y\) 的点,三次操作可以到达所有可以表示为 \((a+c,b)\) 且满足 \(0<a<b<c\) 的点。同时,我们随时从 \(a\) 中减去 \(1\),往 \(c\) 中加上 \(1\)。所以直接钦定 \(a=1\),所以只要满足 \(y>1\) 且 \(x-y>1\) 的 \((x,y)\) 就可以在三步内到达。
如果无法在两次或者三次内到达,就无解。
B. Multiple Construction
Solution 1
构造如下:\(n,n−1,n−2,...,1,n,1,2,...,n−1\)
- 对于最大数 \(n\),让它的两次出现间隔恰好为 \(n\)。
- 对于其他数 k,让两次出现对称地分布在数组中间,使他们的距离为 \(2k\)。
Solution 2
考虑直接强化条件,把是 \(x\) 的倍数改成直接等于 \(x\),那我们就是要让 \(a_i\) 和 \(a_{i+x}\) 同时等于 \(x\),那考虑 \(n\) 在右边放, \(n-1\) 在左边放,然后这样循环交替。但是你会发现 \(a_n\) 会同时被 \(n-1\) 和 \(n\) 覆盖,也就是只有 \(n-1\) 和 \(n\) 会冲突,所以最后会呈现这个样子。
假设 \(n=10\)
\(\{9,7,5,3,1,1,3,5,7,9(10),8,6,4,2,0,2,4,6,8,10\}\)
然后你会发现有个地方没被覆盖,所以把 \(9\) 直接移过去,那就是这样
\(\{1,7,5,3,1,9,3,5,7,10,8,6,4,2,9,2,4,6,8,10\}\)
然后你把 \(a_1\) 改成 \(1\) 就行了。
\(n\) 是奇数同理。
C. Rabbits
注意到,每一个子串 \(11\) 都会将问题分割成两个子问题,因为位于相对两侧的兔子无法相互影响。
考虑对每个子问题进行操作。发现如果存在偶数个连续的 \(0\),我们可以让他们一半向左,一半向右,这样他们就全部跳不了了。容易发现,两个跳不了的字符串恋连起来还是跳不了,所以可以直接把这偶数个 \(0\) 删掉。
现在每个子问题只有两种情况:单独一个 \(0\),或者 \(010101\) 交替。
单独一个 \(0\) 显然不合法。考虑 \(010101\) 交替的情况。发现对于 \(010\) 我们可以一个向右,一个向左从而使他们跳到相同的位置上。所以对于任意多个 \(010\) 都可以删掉。所以,对于 \(010101\) 交替的情况,如果 \(0\) 的个数为偶数,就可以最终使兔子不跳,否则不行。
D. Game on Array
以下 \(x\) 的价值就是 \(x\) 的出现次数。
首先一个很简单的观察,先手最终的得分一定比后手大。
考虑两个人的最优决策是什么,第一想法是找价值最大的选,但这个想法是不对的,考虑这样:
\(\{1,10,10,10,10,10\}\)
如果先手先选了一个 \(10\),那么后手会一直跟着先手选,直到最后变成 \(\{1,1,1,1,1,1\}\),然后后手全部选完。
那么先手就是 \(5+5+5+5+5=25\),后手是 \(5+5+5+5+6=26\)。
所以在这个例子中先手要先选 \(1\)。
那么通过这个例子中可以观察出来,在最优决策中,先手和后手肯定会一个拿到 \(\lfloor \dfrac{x}{2}\rfloor\) 次 \(x\),另一个拿到 \(\lceil \dfrac{x}{2}\rceil\) 次 \(x\)。所以说关键在于谁比对方多拿 \(1\) 次,如果 \(x\) 是偶数就不用管了,如果 \(x\) 是奇数就相当于谁先抢到 \(x\) 的一血谁就会多拿一次 \(x\),那么就按 \(cnt_x\) 排序轮流拿就行了。
E. Maximum OR Popcount
预处理 \(cost(x)\) 表示增加 \(x\) 个 \(1\) 需要的代价。
先按照原数组计算最大OR,记这个值为 \(w\)
我们贪心的从低位到高位处理每个位在 \(w\) 上为 \(0\) 的位置,先计算出仅让这一位变成 \(1\) 的最小代价,然后可能会有一些更低位从 \(1\) 变成 \(0\),我们计算出将他们都变成 \(1\) 的代价。
F. Exchange Queries
对于 \((x, y)\),若满足 \(p_x > p_y\) 或 \(s_x > s_y\),则从 \(p_x\) 向 \(p_y\) 连一条有向边。
最终对连完边的图跑一个强连通分量,答案是:
其中 \(\text{size}_i\) 是每个强连通分量的大小。
直接 \(O(n^2)\) 连边不可行,因此考虑优化:
我们只对相邻的 \(p\) 值连边:即对 \((p_x, p_x - 1)\) 连边。只有当出现交叉情况时才需要额外连边:
即存在 \((x, y)\) 满足 \(p_x > p_y\) 且 \(s_x < s_y\),此时连一条反向边 \(p_y \rightarrow p_x\)。
类似地,我们连反向边的时候只需要考虑相邻的 \(s\) 值 \((s_x,s_x+1)\)
考虑一对 \((x, y\),满足:
- 在 \(p\) 序列中有路径:
\(p_x \rightarrow p_x - 1 \rightarrow \cdots \rightarrow p_y\) - 且 \(s_y = s_x + 1\),即存在反向边 \(p_y \rightarrow p_x\)
则区间 \([p_y, p_x]\) 形成一个强连通分量。
我们用 \(p_y\) 代表该分量,并对区间 \([p_y + 1, p_x]\) 进行区间加 \(1\)。最终我们需要统计值为 \(0\) 的位置。两个 \(0\) 之间的距离即为每个强连通分量的大小。

浙公网安备 33010602011771号