CF做题记录
CF1550
观察样例可得:满足条件当且仅当初始序列满足 ,然后选择 个位置 ,剩下位置 ,其中 为任意非零整数。对这个计数即可。枚举最靠前的减的位置然后枚举最靠后的加的位置计数,然后用上指标求和优化即可。
二分答案然后用状态压缩dp判断。设 表示已经完成集合 中的要求时最靠前的位置,转移十分显然。需要预处理长度为 且全是小写字母 的字符串能放的位置。
考虑到可达性,将该问题转化为一个图论问题:在 之间连接边权为 的边表示偏移量大小。这样如果存在一条从 到 的路径满足经过边权最大值 不超过 则答案为Yes,否则为No。
根据经典结论:任意两点间的任意路径上边权最大值的最小值等于在最小生成树简单路径上的边权最大值。因此只要建出最小生成树即可。这里考虑使用boruvka算法。现在关键在于如何对一个联通块求出以它连向其它连通块的边中权值最小的那一条边。枚举联通块内的每个点 ,要求最小的 使边权尽量小,只要 距离 尽量小。使用set lower_bound即可。
CF1592
CF1592C Bakry and Partitioning
首先题目不要看错!!接下来可以转化为是否存在三个连通块使得其内部点的点权异或和均为sum,其中sum表示所有点权异或和。只有两种情况:1.存在 满足其子树内均存在某个子树异或和为sum 2.存在 满足 是 的祖先且 子树异或和为0, 的为sum。dfs判断即可。
需要找的其实是最大边权。根据询问次数考虑二分,关键是如何保证每次二分时点集都是联通的。直接在欧拉序上二分即可。(求欧拉序不要写错)
与大于异或意味着存在某一二进制位满足更高的位都一致但是当前位与是1而异或是0,即这一位全部是1且有偶数个,因此区间长度一定为偶数。考虑前面的位相同,分0/1两种情况:1.存在0且有偶数个1。2.全是1且有奇数个。第二类情况显然不会出现,而对于第一种情况,可以排除掉存在0这一条件,因为这样答案不会变大。于是我们枚举当前位,对数列做前缀异或和,那么前面的位相同意味着值相等。用vector存下值为i,下标奇偶性为0/1的下标,然后扫一遍同时得到最大值即可。
CF1580
CF1580B Mathematics Curriculum
所有包含这个数的区间中,不同的最大值的个数恰有 个意味着 的后缀最大值和 的前缀最大值个数,而这就是这个数在排列建成的笛卡尔树中的深度(注意这个转化)。于是记 表示长度为 的排列中深度为 的点有 个的方案数,dp即可。
根号分治。首先先进行差分答案数组 ,最后再前缀和回来。对于 的点暴力做。对于 的点, 的取值只有 种,因此可以用数组 维护 数组中下标除以 余 位置的答案,那么每次的贡献就是区间加,仍然可以转化为差分+前缀和。复杂度为 。
CF1601
与运算的一个性质是每个二进制位相互独立。对每个二进制位进行考虑,假设该位总共有 个1,那么容易发现 合法当且仅当 。因此最终答案就是所有 的最大公约数的约数。
可以直接dp,然后使用数据结构进行优化。也可以直接建图后跑01bfs,但是需要线段树优化建边。
使用如下策略必然能够达到最优解:对 的每个元素 放到满足放入后新产生的逆序对(即前面比 小的数的个数和后面比 大的数的个数)最少的位置。
考虑证明。关键在于每个 都能取到最小值,无关插入顺序。我们考虑将 从小到大地排序依次插入。令 表示在 位置后插入当前的 时新产生的逆序对。那么对于 ,假设它从原来的大于 变成了小于 ,那么相当于对于 ,对于 。而初始时 ,每次相当于前缀加后缀减,那么最小值的位置一定是单调右移,即 越大,其最优位置越靠右。这样不仅每个 均能取到最小值,同时 内部也不会新产生任何逆序对,因此这样一定是最优的。具体实现时使用线段树进行维护即可。
结论:按照第一关键字为 ,第二关键字为 ,第三关键字为 从小到大进行排序。依次考虑是否能选即能获得最大值。考虑证明。对于两个元素 。分三种情况:1. 2. 3. 分别讨论即可。
令 ,那么对于区间 :
按照 进行分类后,可以将问题转化为 的情况。此时从右到左进行考虑,对于每个位置能做出贡献的一定是一个单调递减的序列。维护这个单调栈,然后维护两个数组 分别表示从 出发跳 步后到达的点,以及经过的数的和。每次询问时倍增即可。
CF1603
当 时答案可以为 。否则考虑令 ,然后将 代入得 。大胆令 ,然后由于 ,因此再大胆令 ,则 ,发现满足 ,因此答案即为 。
先考虑对一个序列求出其“extreme value”。考虑从后往前找到第一个 满足 。容易发现至少需要将 分为 尽量平均的份才能满足条件。考虑到需要让操作总数尽量少,因此需要让操作后最小的数尽量大,因此恰好将 分为 就是最优的。令 ,则 。然后 ,将 替换为 ,继续进行上述操作即可。最终的 就是答案。
对于原问题,直接做可以做到 。优化考虑dp。令 表示有多少 满足 且从 开始操作到 时该序列的第一个数为 。转移十分trivial,按照上面的过程模拟即可,即 。可以发现对于状态 ,其对答案的贡献为 。容易发现状态数事实上仅有 个,直接dp即可。
考虑 到底是什么。
可以线性预处理。然后我们对于每个 求出每个 处的 的前缀和,那么 就可以做到 求出了。
对于 我们显然有转移方程: 。直接做是 的,考虑优化。首先是减少状态数。可以发现 ,而当 时 取得下界。对于最小的 满足 ,我们考虑取 ,在这样的情况下所有的 同时取得最小值,显然 是最小的,答案就是 ,不需要dp。同时当 更大时答案仍然能取得最小值 。
现在只需要考虑 的 了,但复杂度仍然是 的。考虑优化转移。观察转移方程可以发现其形式非常经典,于是我们可以大胆猜想 满足四边形不等式。事实上的确如此,按照定义即可证明。那么令 表示 的最优转移位置,就有 ,即决策点单调不左移。因此采用分治的做法就可以对于一个 在 的复杂度求出所有的 了。
总时间复杂度 。
ps:即使每次转移时暴力根号地计算 ,不知道为何也可以通过。
CF1588
首先通过二分可以在30次询问下找到 的值。接下来不妨设 ,那么我们再询问 这两个区间,设其答案分别为 ,那么可以得到 ,联立即可解出 ,从而求出 。
容易发现一个序列 是winning的当且仅当 且对于所有奇数 都有 ,对于所有偶数 都有 。证明可以考虑 一定和 一起被减去,然后以此类推下去。
对这个东西计数方法很多,在这里介绍一种比较简便的做法,即枚举右端点,同时使用两个set分别维护当前情况下的所有奇左端点和偶左端点。右端点向右移动一步时,加上此位置的贡献,然后排除掉不满足前缀交错和不小于0的左端点,因为在后面的右端点中它们也不可能合法了。最后统计其中0的个数,贡献到答案中即可。
可以发现点 到线段 的距离是 到射线 和到射线 距离的较大值。于是我们可以枚举点 ,然后 求出所有的 使得所有点距离射线 的距离都不大于 。最后 枚举统计答案即可。
考虑以 为半径为 圆心作圆,那么如果某个点在圆内,那么其到射线的距离一定不大于 。否则我们考虑点 ,如下:
如图所示, 为切线, 为线段 上一点满足 , 为 垂线, 类似。
根据三角形全等可以发现 。因此 距离射线 不大于 当且仅当射线 在 以内。注意 是一个定角,于是可以将所有点对应的角求交,然后看哪些射线在该公共角内即可。
CF1588F Jumping Through the Array
请参见wlzhouzhuan的博客。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现