Codeforces Round #696 (Div. 2)

AC代码

A. Puzzle From the Future

(a_1 = 1),可以保证(c)没有前导零且(c_1)尽可能大。

此时,(d)的位数越多必定比(d)位数小的大,通过保证(c_i e c_{i +1})即可确保(d)(n)位。

在保证(c_i ge c_{i +1})时,前面的(c_i)需要尽可能大,所以需要尽可能的令前面的(a_i = 1)

B. Different Divisors

猜结论:(a)只有(4)个因子,(1, p_1, p_2, p_1p_2)。其中,(p_1,p_2)皆为素数,(a = p_1p_2)

然后线性筛跑个素数表,(p_1 = f(1+d), p_2 = f(p_1 + d)),其中(f(x))为大于等于(x)的最小的素数,二分一下就可以(O(log n))找到。

C. Array Destruction

观察:如果较大的(a_i)没消掉,那么必不可能删完。所以每步操作都必须包含当前剩余最大的(a_i)

用一个multiset保存数组(a)的可重集。

如果当前(x)已经确定了,那么剩余的元素删除过程就可以(O(n log n))模拟,并确定是否可以删完。具体的模拟过程就是,当前(x)已知,参数之一(v)被确定为可重集中最大值,那么剩下的参数也被确定为(x - v),如果可重集中包含这个元素就表示可以操作,(x)更新为(v),反之不可行。重复(n)次。

枚举第一步是哪一个元素和(a_{2n})配对,然后看是否存在可行解。总的复杂度为(O(n^2 log n))

D. Cleaning

观察1:如果可行,那么从左往右依次删除,必定可以删完。记(d_i)为第(i)堆之前的步骤完成后,第(i)堆剩下的石头数量。即(d_i = a_i - d_{i - 1})

观察2:假设(a_i)固定,则有可行解当且仅当(forall i in [1, n], d_i ge 0)(d_n = 0)

如果交换(a_i)(a_{i + 1}),那么就是(d_i)单点修改,然后后缀下标为奇数的位置都加上某个值,下标为偶数的位置都加上某个值。这一步具体手推一下样例应该就可以看出来。

此时只需要保证(d_i ge 0),前面没有(d_i < 0),修改后后面也没有(d_i < 0),修改后(d_n = 0)

其实并不需要真的去做加减的修改,因为修改后后面没有(d_i < 0)只需要后面的最小值修改后不小于零。

然后只需要实现区分下标奇偶的区间最小值就可以了,两棵线段树或者两个ST表就可以实现。

原文地址:https://www.cnblogs.com/zengzk/p/14300878.html