CF R1019
Problem A
正整数范围内,长度为 \(n\) 的漂亮序列 \(x\) 的定义:存在与之长度相等、元素互不相同的序列 \(y\),使得 \(\forall\text{ }i,j\in[1,n],x_iy_i=x_jy_j\)。给一个长度为 \(n\) 的正整数序列 \(a\),求最长的子序列 \(a'\),使 \(a'\) 为漂亮序列。\(t\) 组数据。
\(1≤t≤500,1≤n≤100,1≤a_i≤n\)。
点击查看题解
显然,\(x\) 是漂亮序列的必要条件为 \(x\) 内的元素互不相等。下面是充分性证明:令 \(M=\prod x_i\),则 \(y_i=M/x_i\),符合题意。
1 |
|
Problem B
需要用一根手指以及只有 0 和 1 两个按钮的打字机打出一个长度为 \(n\) 的 01 字符串 \(s\)。有两种操作:把手指放在另一个按钮上,或者按按钮。刚开始手指在按钮 0 上。可以选择翻转 \(s\) 内的任一个子区间,使得操作次数尽量少。求最少操作次数。
\(1≤n≤2\times10^5\)。
点击查看题解
减少操作次数的原理是翻转合并了一些数字相同区间,减少切换次数。由于翻转改变的是两头的数,内部和外部均不影响,所以最多减少 \(2\) 步操作次数。由于刚开始在按钮 0,可以将 \(s\) 开头插入一个 0,方便统计切换次数,以判断可以减少几步操作。
1 |
|
Problem C
定义长度为 \(m\) 的数列的中位数是数列中第 \(\lceil m/2 \rceil\) 小的数。现在给一个长度为 \(n\) 的正整数数列 \(a\) 和正整数 \(k\),询问能否将数列分成三个连续的子数列 \(a_{1\sim l-1},a_{l\sim r},a_{r+1\sim n}\),这三个子数列的中位数分别为 \(q_1,q_2,q_3\),组成数列 \(q\),使得 \(q\) 的中位数小于等于 \(k\)。
\(3≤n≤2\times10^5, 1≤k≤10^9,1≤a_i≤10^9\)。
点击查看题解
此题不必使用对顶堆等求出具体的中位数。对于一段区间,只需满足小于等于 \(k\) 的数字数量 \(\ge\) 大于 \(k\) 的数字数量,即可判断其中位数是否小于等于 \(k\)。令小于等于 \(k\) 的数字贡献为 \(-1\),大于 \(k\) 的数字贡献为 \(1\),利用前缀和或后缀和可以算出某个区间的中位数是否小于等于 \(k\)(区间贡献和小于等于 \(0\))。
只需要满足三个 \(q\) 中有两个 \(\le k\),即可满足题意。分类讨论:
- 前缀、后缀均满足;
- 前缀、后缀只有一个满足;
- 前缀、后缀均不满足。
第一种情况:只需找出一个前缀和一个后缀,贡献和小于等于 \(0\) 即可。可以利用取 min 前缀 / 后缀和解决。
第二种情况:例如前缀满足,需要找出一个后缀,减去这个后缀之后中段小于等于 \(0\) 即可。可以利用后缀和减去取 max 后缀和解决。注意,企图使用“合法前缀 + 一个小于等于 \(k\) 的数字”的组合来判断是错误的。
第三种情况:不满足题意,输出 “NO”。
1 |
|
Problem D
定义极大/小值:若 \(a_i\) 相邻的两个数(若 \(i=1\text{ or }n\),则为相邻的一个数)都比 \(a_i\) 小/大,称 \(a_i\) 为极大/小值。
现给出长度为 \(n\) 的某排列 \(p\),反复进行以下操作,直至剩余一个元素:
- 删除所有非极小值元素;
- 删除所有非极大值元素。
令数组 \(b\) 的定义为:若 \(p_i\) 在第 \(k\) 次操作被删除,则 \(b_i=k\);若 \(p_i\) 为最后剩下的那一个元素,则 \(b_i=-1\)。
现在给出 \(b\),求出任意一个满足的排列 \(p\)。
\(2≤n≤2\times 10^5\),可以证明 \(b_i\) 最大不超过 \(\lceil\log_2 n\rceil\)。
点击查看题解
考虑贪心。
- 由于 \(n\) 为最大值,一定在第一轮被删除;\(n\) 被删除后,由于 \(n-1\) 成为了新最大值,要么第一轮被删除要么第三轮被删除。
- 显然任意时刻不会有两个相邻的极大/小值,不可能连续出现两个非 1(当前考虑的最小 \(b\) 值)。可以一层层递归考虑,每一层需要不是极大/小值,就直接一次填最小/大的数。
得到贪心策略:\(b_i=1,3,...\) 的位置从大往小填,\(b_i=2,4,...\) 的位置从小往大填;\(b_i\) 相同的连续段要单调上升/下降地填,双指针循环就行。例如(数字仅代表相对大小):
1 | 1 1 1 . . 1 1 . 1 1 1 . . 1 |
如果考虑利用建图跑拓扑排序,由于不易利用好所有的大小关系进行建图,做法较复杂。
1 |
|
Problem E
给定正整数 \(k\) 和长度为 \(n\) 的整数序列 \(a\)。可以进行以下操作:
选取两个索引 \(i,j\),要求 \(a_i+a_j=k,i\not=j,1\le i,j\le n\);接下来,可选取整数 \(x\in[0,a_i]\),使 \(a_i\gets a_i-x,a_j\gets a_j+x\)。
可以证明,如果有解,最多进行 \(3n\) 次这样的操作,使得 \(a\) 变为一个单调非降序列。
请给出每一步操作方法,或者说明无解。
\(4≤n≤2\times10^5, 1≤k≤10^9,0≤a_i≤k\)。
点击查看题解
构造题。
如果不存在 \(a_i+a_j=k\),操作则无从谈起。如果存在,则一定有解,采取以下策略。
可以将 \(a_i\) 变为 \(0\),\(a_j\) 变为 \(k\),之后设法使得 \(a_1=0,a_n=k\)。
对于一个数列,排为有序数列最少的交换次数为 \(n-l\),其中 \(l\) 为循环节的数量。在一个循环节内,各元素只需要在循环节内交换即可排好序。
选取一个未排好的循环节中的任意一个元素,设为 \(a_q\)。之后,只需要两步操作即可实现一次交换:
- 令 \(i=n,j=1,x=a_q\)。此时,\(a_1=a_q,a_n=k-a_q\)。
- 令 \(i=q,j=n,x=a_q\)。此时,\(a_q=0,a_n=k\)。之后,坐标 \(q\) 成为 \(0\) 的位置,坐标 \(n\) 为 \(k\) 的位置,继续选取循环节中的下一个元素进行第一步操作,直至坐标 \(1\) 成为 \(0\) 的位置。
1 |
|