CF1561

Codeforces Round #740 (Div. 2, based on VK Cup 2021 - Final (Engine))

D - Up the Strip

题意

给出一个数字 nn 表示初始的数字,你可以对当前的数字(比如说是 xx)做若干次变化,变化包含下列两种:

  1. 选择一个数字 y[1,x1]y\in[1,x-1],将现在的数字 xx 变为 yxy-x

  2. 选择一个数字 z[2,x]z\in[2,x],将现在的数字 xx 变为 xz\left\lfloor\frac{x}{z}\right\rfloor

求将初始数字 nn 变为 11 的不同的操作有多少种?

答案对 mm 取模,每次会给出 mm

数据范围:2n4×106,108<m<1092\leqslant n\leqslant 4\times 10^6, 10^8 < m < 10^9

思路

求不同操作的个数,可以用dp完成,令 f(n)f(n) 为将数字 nn 转变为 11 的不同操作个数,则转移为:

f(n)=i=2nf(ni)+i=1n1f(i)f(n)=\sum_{i=2}^nf(\left\lfloor\frac{n}{i}\right\rfloor)+\sum_{i=1}^{n-1}f(i)

右侧第一个式子可以使用数论分块在 O(n)O(\sqrt n) 内完成,然后从1到n计算对应的 f(x)f(x),右侧用前缀和即可 O(1)O(1) 求出。

总复杂度:O(NN)O(N\sqrt N),于是 Up the Strip (simplified version) 就可以通过了。

如果要通过 n=4×106n=4\times10^6 的数据,时间复杂度不能超过 O(NlogN)O(NlogN),空间复杂度不能超过 O(N)O(N)(128Mb)。

考虑 ff 中相邻两项之间的关系,下面列式观察:

f(n)=i=2nf(ni)+i=1n1f(i)=i=2n1f(ni)+i=1n2f(i)+f(1)+f(n1)f(n1)=i=2n1f(n1i)+i=1n2f(i)\begin{aligned} f(n)&=\sum_{i=2}^nf(\left\lfloor\frac{n}{i}\right\rfloor)+\sum_{i=1}^{n-1}f(i)\\ &=\sum_{i=2}^{n-1}f(\left\lfloor\frac{n}{i}\right\rfloor)+\sum_{i=1}^{n-2}f(i)+f(1)+f(n-1)\\ f(n-1)&=\sum_{i=2}^{n-1}f(\left\lfloor\frac{n-1}{i}\right\rfloor)+\sum_{i=1}^{n-2}f(i) \end{aligned}

不难发现 f(n)f(n)f(n1)f(n-1) 中第一项只有分子发生了变化,从 n1n-1 变为 nn

那么只需要考虑,分母在何时会发生变化即可。

i=3i=3 时,那么只有当 n=3,6,9,,3kn=3,6,9,\cdots,3k 时,n3\left\lfloor\frac{n}{3}\right\rfloorn13\left\lfloor\frac{n-1}{3}\right\rfloor 才会发生变化
而且只是从 n13=n31\frac{n-1}{3}=\frac{n}{3}-1 变为 n3\frac{n}{3}

所以 f(n)f(n)f(n1)f(n-1) 的转移可以写成:

f(n)=2f(n1)+f(1)kn,k2f(nk1)+kn,k2f(nk)f(n)=2f(n-1)+f(1)-\sum_{k|n,k\geqslant 2}f(\frac{n}{k}-1)+\sum_{k|n,k\geqslant 2}f(\frac{n}{k})

由于 n2+n3+n4++nn=O(nlogn)\frac{n}{2}+\frac{n}{3}+\frac{n}{4}+\cdots+\frac{n}{n}=O(n\log n),所以如果我们直接预处理能整除 nnkk 时,在空间上会爆掉的。

所以正确的做法有如下两种:

他们时空间复杂度都一样为:时间复杂度 O(nlogn)O(n\log n),空间复杂度 O(n)O(n)

法一:

对每个 nn 求它所有的因数(需要先用筛法求出素数表,然后求 nn 对应的素因数,最后暴力枚举每个素数的个数)。

法二(更优美的做法):

就是考虑倒序求解,从 1n1\sim n 求解,考虑每个数 f(k)f(k)2k,3k,4k,2k, 3k, 4k, \ldots 的贡献。

E - Bottom-Tier Reversals

题意

给出 11nn 的排列, a=[a1,a2,,an]a = [a_1, a_2, \ldots, a_n],其中 nn奇数

你可以进行一次操作,每次操作可以选择当前序列的前 kk 项,kk必须为任意的奇数,然后反转他们,也就是将 aia_iaki+1a_{k-i+1} 交换位置。

如果你可以在不超过 5n2\frac{5n}{2} 次操作后完成当前序列的排序,先输出反转的次数,再输出每次反转的长度。

如果不能则输出 1-1

数据范围:3n20213\leqslant n\leqslant 2021

思路

性质:如果每次反转的区间长度为奇数,那么反转元素的下标的奇偶性不发生变化,如 [1,4,3,2,5][5,2,3,4,1][1, 4, 3, 2, 5]\rightarrow [5, 2, 3, 4, 1],奇偶性不变。

那么由于每次反转只能反转奇数长度,所以一定有 aia_iii 的奇偶性相同,也就是 aii(mod2)a_i\equiv i\pmod 2

下面用具体操作证明这是一个充要条件。

由于又限制了每次反转只能在开头,开头位置无法改变,但末尾位置如果已经对应好了,则可以改变,所以考虑当前的末尾元素是否满足条件:

  • an=n,an1=n1a_n=n, a_{n-1}=n-1,则不需要交换,继续考虑 n2n-2

  • anna_n\neq nan1n1a_{n-1}\neq n-1,则考虑下面5次交换,使得 an=n,an1=n1a_n=n, a_{n-1}=n-1

  1. ak=na_k=n(注:kk 为奇数),反转 [1,,k][1,\ldots, k]

  2. at=n1a_t = n-1(注:tt 为偶数),反转 [1,,t1][1,\ldots, t-1]

  3. at=n1a_t=n-1,反转 [1,,t+1][1, \ldots, t+1]

  4. 反转 [1,2,3][1, 2, 3]

  5. 反转 [1,,n][1,\ldots, n]

上面步骤可以在草稿纸上模拟完成,便于理解。

于是总操作步骤一定不会超过 5(n1)2\frac{5(n-1)}{2} 步。

只需模拟上述操作即可,时间复杂度 O(n2)O(n^2)


CF1561
https://wty-yy.github.io/posts/25882/
作者
wty
发布于
2021年8月26日
许可协议