Codeforces 1800+ 乱做
- CF1328D [dif:1800]
- CF1398D [dif:1800]
- CF1438C [dif:2000]
- CF1400D [dif:1900]
- CF1366D [dif:2000]
- CF1348D [dif:1900]
- CF1370D [dif:2000]
- CF1359D [dif:2000]
- CF1359E [dif:2000]
- CF1355E [dif:2100]
- CF765F [dif:3100]
- CF1416C [dif:2000]
- CF1110E [dif:2200]
- CF1101D [dif:2000]
- CF1513D [dif:2000]
- CF1467D [dif:2200]
- CF1006F [dif:2100]
- CF1473E [dif:2400]
- CF1637E [dif:2100]
- CF1628C [dif:2300]
- CF1166E [dif:2100]
- CF1088D [dif:2000]
- CF1408F [dif:2300]
CF1328D [dif:1800]
\(T\) 组询问,每次给一个大小为 \(1\) 的环,点 \(i\) 的类型为 \(a_i\),给每个点染色,如果相邻点类型不同则颜色必须不同,求最小使用的颜色数,输出方案,颜色编号从 \(1\) 开始。
答案只可能是 \(1,2,3\)。讨论亿下即可。
CF1398D [dif:1800]
给你三个序列 \(r,g,b\),分别有 \(R,G,B\) 个元素,每次从两个序列中挑两个没选过的元素 \(x,y\),贡献为 \(x \times y\),可以挑无数次,问最大贡献。
贪心寄了!
反悔贪心也寄了!
考虑 DP,设 \(f_{i,j,k}\) 表示 \(r\) 序列中前 \(i\) 个元素, \(g\) 序列中前 \(j\) 个元素,\(b\) 序列中前 \(k\) 个元素的最大贡献。(先排序),显然有转移方程:
CF1438C [dif:2000]
给你一个 \(n \times m\) 的矩阵,每个位置可以选择是否 \(+1\),输出最后的矩阵使得没有相邻的位置相同。
把他当作一个二分图,按照 \(i + j\) 的奇偶性讨论即可。
为什么这种题在 cf 能评 2000 ???而且还附带一堆高深算法
CF1400D [dif:1900]
给你一个长度为 \(n\) 的序列,寻找满足 \(a_i = a_k, a_j = a_l\) 的 \((i,j,k,l)\) 对数。\(n \le 3000\)
枚举 \(j,k\) 的位置,然后算算两侧有多少相同的,乘法原理统计即可。
CF1366D [dif:2000]
给你 \(n\) 个数,对于第 \(i\) 个数 \(a_i\),找到它的两个因子 \(d_1, d_2\) ,使满足 \(\gcd(d_1+d_2, a_i) = 1\)。
\(n \le 5 \times 10^5, a_i \le 10^7\)
首先,如果 \(x = p^k\) ,那么一定无解,因为任何因子都是 \(p\) 的倍数。
然后,先说结论,设 \(a = p^k q\) 且 \(p \not \mid q\) ,则 \(d_1 = p^k, d_2 = q\) 是一组合法解。
考虑证明,已知 \(p^k \perp q\)。
考虑反证法,假设 \((p^k + q) | a\) ,即 \((p^k + q) | p^kq\),可以得到下式
此处 \(d\) 为正整数。
若 \(q | d\),则
不成立。
若 \(q |(p^k+q)\) ,那么 \(q | p^k\) ,与已知条件不符,也不成立。
综上,得证 \(d_1 = p^k, d_2 = q\) 是一组合法的构造。
CF1348D [dif:1900]
开局有一个质量为 \(1\) 的细菌,然后选任意个细菌分裂,质量平分,之后每个细菌质量 \(+1\) ,让所有细菌质量和为 \(n\) 需要几步操作,输出方案。
转化一下题意:假设当前有 \(x\) 个细菌,和为 \(sum\),每次可以将 \(x\) 变为 \([x,2x]\) 中的任意一个数,然后让 \(sum\) 加上 \(x\)。
每次加的越多越好,所以贪心加 \(2x\)。但是最后一次加的数可能小于 \(x\),但是没关系,这次操作可以放在之前 \(\le x\) 的某步操作内,然后按顺序求一遍答案即可。
CF1370D [dif:2000]
给你一个长度为 \(n\) 的序列,选择一个长度为 \(k\) 的子序列,它的贡献是 偶数位的最大值 和 奇数位的最大值 中的较小值,求这个值最小是多少。
\(k \le n \le 2 \times 10^5, a_i \le 10^9\)
假设贡献是偶数位的最大值,就相当于在序列中选 \(\frac{k}{2}\) 个不相邻的数,最大值尽可能小。
可以二分,看看能选的数有没有达到 \(\frac{k}{2}\) 。
奇数位同理。注意要分类讨论一下起点和终点能否选(需要给对方留)。
复杂度是 \(\mathcal O(n \log V)\),其中 \(V = 10^9\)。
CF1359D [dif:2000]
给你一个长度为 \(n\) 的序列 \(a\),设 \(s_i = \sum_{j=1}^{i} a_i\),求 \(\displaystyle\max_{1\le l \le r \le n } \{s_r - s_{l-1} - \max_{l\le i \le r} \{a_i \}\}\) 。
\(n \le 10^5, -30 \le a_i \le 30\)。
枚举最大值 \(a_i\) 的值然后求最大子段和。复杂度 \(\mathcal O(61n)\)。
CF1359E [dif:2000]
给你两个数 \(n,k\),构造一个长度为 \(k\) 的严格递增序列 \(a\),需满足 \(a_i < a_{i+1}\),并且满足
\[(((x \bmod a_1) \bmod a_2) ... )\bmod a_k = (((x \bmod a_{p_1}) \bmod a_{p_2}) ... )\bmod a_{p_k} \]\(p\) 序列是所有 \(1 \sim n\) 的排列。
求构造的合法 \(a\) 的方案数。
设构造序列中的最小值为 \(a\),另一个值为 \(b\),那么要满足
因为 \(b > a\) ,所以左半部分相当于 \(x \bmod a\)。也就是说要满足下面的式子:
设 \(x = yb + t\),则
也就是说 \(a \mid b\) 。
于是我们可以枚举最小值,然后后面只能放它的倍数,用组合数直接算一下方案数即可。
CF1355E [dif:2100]
给你四个值 \(n,A,R,M\),表示有 \(n\) 个数,第 \(i\) 个数为 \(a_i\),目标是让他们变成同一个数,花费 \(A\) 可以让某个数 \(+1\),花费 \(R\) 可以让某个数 \(-1\),花费 \(M\) 可以让一个数 \(+1\) 一个数 \(-1\)。求最小花费。
\(n \le 10^5, 0 \le A,R,M \le 10^4, 0 \le h_i \le 10^9\)。
解决这题的关键需要发现它是一个单峰函数。
设需增加 \(x\) 个,减少 \(y\) 个最优,且 \(y>x\),最终数值为 \(h\)。
如果 \(A+R \le M\),那么贡献为 \(Ax+Ry\) 。一个上升另一个就会下降,显然这是一个单峰函数。
否则,贡献为 \(Mx+R(y-x)\),然后你考虑吧当前的数值 \(h\) 加一或者减一,考虑它的变化量,发现它仍然是个单峰函数。
因此可以三分。为了防止边界出问题,一个技巧是把边界设成 \(r-l<100\),最后一部分暴力枚举。
时间复杂度 \(\mathcal O(n \log V)\)。
CF765F [dif:3100]
给你一个长度为 \(n\) 的序列 \(a\),\(m\) 次询问,每次询问给一个 \(l,r\) ,求 \(\displaystyle\min_{l\le i<j\le r}\{ |a_i - a_j|\}\)。
\(1 \le n \le 10^5, 1 \le m \le 3 \times 10^5, 0 \le a_i \le 10^9\)。
考虑离线,用扫描线枚举右端点然后维护左端点的答案,
考虑新加一个点 \(x\)。
考虑有哪些点对可能有贡献,必定是一个递增的子序列,并且长度不超过 \(\log V\) 。
对于长度 \(\log\) 的证明,设有 \(j<k<i\) 且 \(a_i < a_j < a_k\) ,如果 \(j,k\) 都能作为更新点,那么一定有 \(a_k - a_i \ge 2(a_j - a_i)\) ,不然的话枚举 \(k\) 的时候就能把 \(j\) 更新,所以说这个距离每次可以缩到原来的 \(\frac{1}{2}\),证毕。
然后查询的时候可以从右向左从大向小,用线段树维护答案,主席树维护值域上最靠右的位置。
因为主席树维护的是一个 \(\max\) ,所以只能查一个前缀,所以要从右向左更新答案。
然后就做完了,时间复杂度是 \(\mathcal O(n\log^2n)\)。
CF1416C [dif:2000]
给你一个长度为 \(n\) 的序列 \(a\),异或一个数 \(x\),使它的逆序对最少。
\(1 \le n \le 3 \times 10^5, 1 \le a_i \le 10^9\)。
从大到小按位考虑,只考虑这一位产生的逆序对,算一下填 \(1\) 优还是填 \(0\) 优,直接贪心取。
然后把这一位是 \(0\) 的和这一位是 \(1\) 的分成两部分分治考虑下一位即可。
注意每一位要放到最后一起贪心。
时间复杂度 \(\mathcal O(n \log V)\)。
CF1110E [dif:2200]
给你两个长度为 \(n\) 的序列 \(c,t\),每次可以这样操作:\(c_i \to c_{i+1} + c_{i-1} - c_i\),问能不能将 \(c\) 变成 \(t\)。
这个操作和 NOIP2021T3 可谓是完全一样啊/kx
每次操作相当于交换相邻两数的差值。
那么我们只需要比较一下差值的值域是否相同,首尾是否相同即可判断。
CF1101D [dif:2000]
给你一棵 \(n\) 个点的树,每个点有权值,求一个点数最多且所有点点权的 \(\gcd > 1\) 的链,输出链上点的个数。
\(1 \le n, a_i \le 2 \times 10^5\)。
发现 \(2 \times 3 \times \times 5 \times 7 \times 11 \times 13 \times 17 > 2 \times 10^5\)。
也就是说一个点的质因子最多有 \(7\) 个,那么我们对齐质因数分解,将 \(7\) 个质因子全部存下来进行 DP 即可。
设 \(f_{u,i}\) 表示在 \(u\) 的子树中以 \(u\) 为一端 \(\gcd\) 为 \(a_u\) 的第 \(i\) 个因子能够得到的最长链,\(p_{i,j}\) 表示 \(i\) 的第 \(j\) 个因子。
转移方程:
然后就做完了。
CF1513D [dif:2000]
对于一个序列,若有 \((i,j)\) 满足 \(\gcd_{k=i}^{j} a_k = \min_{k=i}^{j} a_k\) ,则连一条无向边 \((i,j)\),边权为 \(\min_{k=i}^{j} a_k\);若有 \((i,j)\) 满足 \(i+1=j\),连一条无向边 \((i,j))\),边权为 \(p\)。
给定一个长度为 \(n\) 的序列谋求连边所构成图的 MST 的边权之和,多测。
\(n \le 2 \times 10^5, 1 \le p,a_i \le 10^9\)
通过手模或者观察,我们可以发现,如果有一段区间满足 \(\gcd_{k=i}^{j} a_k = \min_{k=i}^{j} a_k\),那么这一段区间内的点都可以联通在一起。
于是我们就想按照 \(a_i\) 从小到大枚举 \(i\),然后暴力向两边扩展加边,因为一个点最多会被右边的点扩展一次,左边的点扩展一次,所以扩展次数是线性的,因为枚举的就是区间的最小值,所以直接判断是否满足 \(a_i | a_j\) 即可。
CF1467D [dif:2200]
一条线段上有 \(n\) 个点,机器人每次只能移动到自己相邻的点上,且不能离开这 \(n\) 个点。每个点都有分数,分别是 \(a_1,a_2,\dots,a_n\)。 机器人将从任意一个点开始时,在线段上移动 \(K\) 次,每到一个点(包括起始点和重复路过的点),机器人的总分就会加上该点的分数。
现在,我们将对这条线段作 \(q\) 次单点点权修改,试求出所有的移动方案的机器人总分的总和。
\(n,k \le 5000, a_i \le 10^9\)
看到 \(n,k\) 数据范围,一定是一个 \(\mathcal O(nk)\) 的算法
设 \(f_{i,j}\) 表示走了 \(j\) 步到了 \(i\) 的方案数,\(g_{i,j}\) 表示从 \(i\) 开始走 \(j\) 步的方案数。发现 \(f_{i,j} = g_{i,j}\),所以只记录一个即可。设 \(t_i\) 表示 \(i\) 这个点一共经过了多少次。所以:
然后就做完了。
CF1006F [dif:2100]
给一个 \(n \times m\) 的网格,每个位置有一个 \(a_{i,j}\)。从 \((1,1)\) 走到 \((n,m)\),每次只能向右或者向下,沿途要异或上 \(a_{i,j}\),求有多少条路径异或和为 \(k\)。
\(1 \le n \le m \le 20, 0 \le k \le 10^{18}\)
发现 \(n+m\) 只有 \(40\),考虑折半搜索?
然后做完了。
CF1473E [dif:2400]
给你一个 \(n\) 个点 \(m\) 条带权无向边的图,无重边和自环。
我们这样规定一条路径的权值,设路径边集为 \(E\),那么路径权值为 \(\sum_{i \in E} w_i - \max_{i \in E} w_i + \min_{i \in E} w_i\)。
求 \(1\) 到第 \(i\) 个点的路径权值的最小值。
\(2 \le n \le 2 \times 10^5, 1 \le m \le 2 \times 10^5, 1 \le w_i \le 10^9\)
弱化一下这个问题,就是一条路径,让一条边权值为 \(0\),一条边权值为 \(2w\),然后求最短路。
一种方式是设 \(dis_{i,0/1,0/1}\) 表示到第 \(i\) 个点,是否已选择边不计权值,是否已选择边权值为 \(2w\)。
另一种方式是建分层图,不过要建两次,一种是先 \(0\) 后 \(2w\),另一种是先 \(2w\) 后 \(0\)。
两种方式本质上是差不多的。
然后跑 Dij 即可。复杂度为 \(\mathcal O(m \log m)\)。
CF1637E [dif:2100]
给定一个长度为 \(n\) 的数组 \(a\)。给出如下定义:
- 定义 \(cnt_x\) 为 \(x\) 在数组 \(a\) 中出现的次数,
- 定义 \(f(x,y)=(cnt_x+cnt_y)\cdot(x+y)\)。
同时,给定由 \(2m\) 个数对 \((x_1,y_1),(y_1,x_1),(x_2,y_2),(y_2,x_2),\cdots,(x_m,y_m),(y_m,x_m)\) 组成的集合 \(S\)。
你需要计算出 \(\max f(u,v)\),要求 \(u,v\) 都出现在数组中,\(u\neq v\) 且 \((u,v)\) 不在集合 \(S\) 中。
这题 codeforces 上的标签给了暴力。
然后我们考虑存出现了 \(i\) 次的数的最大值。不难发现我们最多会存 \(\sqrt n\) 个。
然后暴力枚举一下每一对,一对是否合法直接从集合 \(S\) 中查就好了。
然后就做完了。等等这个做法好像是错的。
如果去和最大值配对不合法,还得考虑次大值。
因此考虑用 vector
把所有次数为某个值的存下来。
然后枚举一下每个数,再枚举次数,然后从 vector
里从大到小枚举每个值判断,找到一组合法的之后直接退出。
算一下时间复杂度,外层枚举有 \(n \sqrt n\) 次查询,vector
中的枚举最多会带来 \(m\) 次查询。
因此复杂度为 \(\mathcal O((n \sqrt n + m) \log m)\)。
看上去是过不了的,也确实过不了,TLE 79 !!!。
然后考虑一些常数上的优化,外层改为倒叙枚举,内层在查询前先判断一下这次的贡献会不会更优,如果不优直接 break
。内层查值判断的时候只找比自己大的,然后你就卡过去了。
其实如果你前两层都用来枚举次数的话,可以做到 \(\mathcal O((n+m) \log m)\)。
CF1628C [dif:2300]
给定 \(n \times n\) 的矩阵 \(a\),求 满足 \(a\) 中任意一个元素等于 \(b\) 中与其相邻的元素的异或和 的矩阵 \(b\) 的异或和。
\(2 \le n \le 1000\),\(n\) 是偶数。
小清新构造题?
首先这是个二分图,奇偶之间不太影响。好像对答案也不影响
然后,你只需要把第一行全填 \(0\),发现剩下的就都固定了。
CF1166E [dif:2100]
有一个长度为 \(n\) (\(n \le 10^4\)) 的内容未知的序列,再给 \(m\)(\(m \le 50\) )个限制,每个限制会给一个位置集合 \(S\),需要让 \(S\) 中所有位置上的数的 \(\text{lcm}\) 严格大于序列里剩下的数的 \(\text{lcm}\),求是否存在一个这样的序列满足所有限制。
找一下这题的切入点,考虑一下集合之间的关系。
发现如果两个集合没有相交,那么一定无解,因为不可能出现我比你大,同时你比我大的情况。
那么合法的情况一定是所有的集合都有交。其实构造方案也非常简单,这个交设为 \(2\),其他为 \(1\) 就好了。不过题目没要求这个。
CF1088D [dif:2000]
交互题,你需要猜一对整数 \((a,b)\),每次你可以询问一组整数 \((c,d)\),系统会回答 \(a \oplus c\) 和 \(b \oplus d\) 的大小关系。询问格式是
? c d
,回答格式是! a b
。你一共有 \(62\) 次询问机会,保证 \(0 \le a, b< 2^{30}\)。
可以先有一次询问 \(0,0\) 确定 \(a,b\) 的大小关系 \(k\)。记 \(c,d\) 为当前确定的部分。
然后从大到小考虑每一位,先询问一手 \(c|(1<<i), d|(1<<i)\) ,如果大小关系相同,说明 \(a,b\) 这一位均为 \(0\) 或者均为 \(1\),然后可以再这一位分别放上 \(1,0\) 再询问一遍确定是 \(0\) 还是 \(1\)。
如果大小关系不同,则可以直接确定这一位是 \(1\) 还是 \(0\)。然后需要重新问一遍去掉 \(i\) 位后面这些位的 \(a,b\) 的大小关系,依次来更新 \(k\)。
CF1408F [dif:2300]
题意:你需要选择 \(q\) 个二元组 \((x_i,y_i)\),每次使得 \(a_{x_i}\) 和 \(a_{y_i}\) 的值变为 \(f(a_{x_i},a_{y_i})\)。\(f(x,y)\) 的值为任意值,对于相同的 \(x,y\),\(f(x,y)\) 的值相同,请你找出一种可能使得对于任意函数 \(f\) 经过 \(q\) 次操作后数列中最多只有 \(2\) 个不同的数。
手模发现对于一个长度为 \(2^k\) 的序列是可以在 \(2^k \log 2^k\) 的次数内化为相同的数。
那么对于一个长度不是 \(2^k\) 的序列,找到最大的 \(k\) 满足 \(2^k \le n\),先对 \([1,2^k]\) 的区间操作一次,在对 \([n-2^k+1,n]\) 这段区间操作一次就做完了。算一下总次数是够的。