头像
憧憬成为AC自动机
编辑于 04-17 18:14 湖北
+ 关注

题解

A 为了避免重复遍历已经被买走的物品,我们引入并查集。 我们定义 fa[x] 表示:“如果我要买第 x 个物品,我实际应该去看的下一个候选物品是谁?” • 初始状态: fa[x] = x。大家都还没卖出去,我想买 x,我就能买到 x。 • 跳跃机制: 当代码中执行 if (find(j) != j) 时,意味着第 j 个物品已经被买走了。此时通过并查集的路径压缩,find(j) 会瞬间返回 j 后面第一个可能还有货的物品位置! • 光速越过废墟: 代码中的 j = find(j);。它直接把指针 j 瞬移到了下一个有意义的位置,中间哪怕有十万个已经卖出的物品,也只需 O(1) 的时间直接跳过。

B 由于是加权单向边,因为你不能回头,所以你走任何一条边都不清楚这条边对后续状态的影响是大还是小,换句话说,当你走过一条边权值小的边,你不清楚这条边后续能经过的边的边权值是大还是小,所以考虑dp,由于体力值很小,所以可以开一个30×5e5的二维数组,状态转移为从u能到达的v点向u转移,第p步的时候从v点到u,dp[p][i]表示u点到i点在p个体力值的时候能获得的最大权值

核心转移方程代码: for(int i=0;i<=30;++i){ for(int j=1;j<=n;++i){ for(auto x:e[j]){ dp[i][j]=max(dp[i][j],dp[i-1][x]+x.w); } } }

C 跟A题一样,没多大差别

D 按照题意模拟即可

E 这题真是抱歉,题目没仔细看一遍。 输出ascii码的和即可

F 对于每种冰棒开一个队列,存这个冰棒的生产时间,对于每个人按到店时间排序,每来一个人,对于他想买的冰棒,不在期限内就pop掉,队列为空或钱不够就把这个人pass掉,买得了就把这个冰棒也pop掉并答案加一。

G 差分序列的引入 处理区间翻转问题,最常用的手段是差分。 定义差分序列 (其中 )。

  • 前缀翻转 :改变了 的相对状态。在差分序列上,仅体现为 发生翻转。
  • 后缀翻转 :改变了 的相对状态。在差分序列上,仅体现为 ** 发生翻转。 注意:差分序列只能确定 之间的相对关系,无法确定具体的绝对值。要确定整个序列,还需要一个基准值(例如 )。 状态映射 对与长度为 的原序列,我们可以映射到一个长度为 的新序列:
  • 差分位:,共 位。
  • 基准位:(或者 ),共 位。 所有的 个差分位,都可以通过一次对应的“前缀翻转”或“后缀翻转”独立地改变状态。 例如:翻转 ,只需要执行一次 Prefix Shift(i)
  1. 最少操作次数分析 我们发现,原序列的 种状态,一一对应差分向量 种取值。
  2. 差分位 :    每一位 如果目标是 (即 ),则必须至少操作一次来产生这个差异。
  3. 基准位 :    如果目标状态的 ,说明相对于初始的“全高能态”,我们需要改变第一位的状态。    - 如果此时已经有某个 被翻转了(比如执行了 Suffix Shift(i+1)), 可能已经随之翻转。    - 如果所有 都是 ,但 需要是 ,则必须执行一次覆盖第一位的操作(如 Prefix Shift(n))。 结论 通过数论与位运算性质推导,该问题可以简化为:
  • 状态由 个独立的差分开关和 个整体偏移构成。
  • 到达某个状态的最少操作次数,等于该状态下 差分序列中 的个数,但存在一种特殊情况:如果需要翻转 却不改变任何差分位(即目标为全 或全 的特定变换),操作次数会产生偏移。 经过数学归纳,总步数公式为:

H

  1. 关键性质分析注意题目中的边失效条件: 时边失效。这意味着随着时间 的增加,可用的边只会减少,不会增加。如果按照时间正序处理,我们需要不断从图中删边并重新计算最短路,这在 的复杂度下是难以承受的。逆向思维:如果我们从晚到早处理询问( 从大到小),那么随着 的减小,满足 的边会逐渐增加。2. 算法选择:Floyd-Warshall 增量更新由于 ,全源最短路通常考虑 Floyd 算法。当我们在图中新增一条边 ,其长度为 时,并不需要重新跑一遍 的 Floyd。我们可以通过这条新边来更新所有节点对 的最短距离:这种增量更新的复杂度仅为 。3. 算法步骤离线处理:将所有询问按照时间 降序排序;将所有边按照承受上限 降序排序。初始化:初始化最短路矩阵 为无穷大,自环为 。双指针遍历:遍历排序后的询问。对于当前询问的时间 :将所有满足 的边加入图中。每加入一条边,执行一次 的动态更新。更新完后,记录当前询问的答案。输出:按照询问的原始顺序输出结果。复杂度分析时间复杂度:排序:。Floyd 增量更新:总共加 条边,每次 ,总计 。在本题中 ,对于 1-2 秒的时限来说稍显吃力,但由于很多边可能并不会更新最短路(即代码中 eg[idx].d >= f[u][v] 的剪枝),实际运行效率会很高。空间复杂度:,主要是存储距离矩阵和询问信息。

I 本题需要分三种情况讨论: 在进行一次循环后,我们可以得到一个新的清醒度num,将num和原清醒度x进行对比。 (1) num<x,则代表每经过一次歌曲循环,清醒度都会减小,那么一定存在多次循环后清醒度满足条件。 (2)num>x,那么每次播放歌曲,都会使清醒度增大。那么能满足条件的清醒度只可能存在于第1次播放,在第1次播放的时候判断即可。 (3)num=x,这个又需要分两种情况进行讨论:第1种情况是原x>k,那么在第1次播放的时候判断即可。第2种情况是x=k,那么我们需要在播放第1次和第2次歌曲去判断,记录符合条件的清醒度持续的最长时间,如果t<n,直接将最长时间与t进行对比,需大于等于t。但是如果t>=n, 那么我们则只需要最长时间大于等于n即可(只要满足此要求,那么在循环多遍后,无论t多大,都能满足)。

J 题目要求我们计算: floor(N / M) % 10007。 因为 N 极大,根本无法用普通数据类型直接表示。我们设 N 除以 (10007 * M) 的商为 q,余数为 R,则有: N = q * (10007 * M) + R 将其代入题目要求的式子中: floor( [q * 10007 * M + R] / M ) % 10007 = (q * 10007 + floor(R / M)) % 10007 = floor(R / M) % 10007 核心结论: 我们不需要知道 N 到底多大,只需要求出 N 对 (M * 10007) 取模的结果即可! 在此,我们令基础模数 Mod_base = M * 10007。 三、 核心思维二:扩大 9 倍模数,完美避开逆元 N 是由一段段数字拼接的。假设要在当前数字后拼接 L 个数字 c。 这一段纯数字的值,其实是一个等比数列求和公式: 。 拼接后的新值为: 新值 = 旧值 致命问题: 我们需要在模 Mod_base 意义下计算这个式子。但是式子中有一个“除以 9”。如果输入的 M 是 3 或 9 的倍数,那么 9 在该模数体系下是不存在逆元的,常规的除法取模操作直接失效! 破局神技: 直接将模数扩大 9 倍! 令最终计算模数 MOD = 9 * M * 10007。 我们在这个扩大的 MOD 环境下计算出 的余数。因为 在数学本质上绝对是 9 的倍数,所以我们算出大模数下的余数后,直接在普通整数代码中除以 9,就能得到绝对正确且没有精度损失的等比数列和! 最后得出答案后,由于公式最后一步是 (ans / m)%10007,这个提前扩大的 9 倍误差会被自然而完美地消除。 四、 核心思维三:十进制快速幂处理超长字符串 本题中,重复次数 L 是一个长度可达 的字符串。求 该怎么做? 我们可以从左到右遍历字符串的每一位。 假设当前累计的幂次结果为 pre,读取到字符串下一位数字 d 时,新的幂次结果相当于: 。 为了极速计算 pre^10,采用手动二进制展开的极致优化: 。 这使得我们对每个字符的处理降到了绝对常数级别,摒弃了繁琐的欧拉降幂和高精度比较。 K 为了满足“非递减”条件并求出方案数,我们可以将其转化为完全背包问题的一个变种:

  • 物品:所有的完全平方数 ,其中
  • 限制:恰好选出 个物品,总和为

定义状态 表示:使用 个盒子,凑出糖果总数为 的方案数。

转移方程: 为了保证非递减,我们有两种思路。最高效的一种是借鉴“整数拆分”的技巧。 考虑到所有物品都是平方数,我们可以枚举当前使用的最小平方数是多少。但更简单的方法是直接套用背包: 设 为可选的正平方数集合。 注意:由于盒子可以放 也是平方数),且要求非递减。实际上这等价于:从可选的平方数集合中,选出不超过 个正平方数,使其总和等于 剩下的盒子全部填 即可。

但为了方便记录路径,我们采用如下 DP: :使用了前 正平方数),当前总和为 时,所使用的盒子总数 为了输出任意一组解:

  1. 在 DP 转移时,记录 pre[i][j],表示当前状态是从哪个状态转移过来的(或者记录当前选了几个某种平方数)。
  2. 如果 ,说明剩下的 个盒子填 即可。

L

  1. 题目核心我们需要从长度为 的数组中找到两个数 ),使得它们的按位与(Bitwise AND)结果最大。优先条件:按位与的结果最大。次要条件:若最大值相同,输出下标组合字典序最小的一组(即 越小越好,若 相同则 越小越好)。2. 贪心策略按位与运算的特点是:高位的一位 胜过低位所有的 。例如:二进制 (8) 大于 (7)。为了让结果最大,我们应该从最高位(第 31 位)向最低位(第 0 位)遍历:检查当前所有候选数字中,在这一位为 的数字个数是否 。如果满足:说明最终的最大结果在这一位可以为 。为了保住这个高位的 ,我们必须剔除掉所有在这一位为 的数字,剩下的数字进入下一轮筛选。如果不满足(即在这一位为 的数少于 2 个):说明这一位无法通过两个数按位与得到 ,我们只能放弃这一位,保留当前所有的候选数字进入下一轮。

全部评论

(0) 回帖
加载中...
话题 回帖

等你来战

查看全部

热门推荐