:root { --bg-color: #ffffff; --text-color: #333333; --header-bg: #f5f5f5; } .night-mode { --bg-color: #1a1a1a; --text-color: #e0e0e0; --header-bg: #2d2d2d; } body { background: var(--bg-color); color: var(--text-color); } .header { background: var(--header-bg); }

【OI 档案-破碎的往事】校队

建立

可能是学校准备在信竟生的培养上下大功夫,所以组建了信竟队,并进行了初步的筛选,入队检验考的是 CSP-J 级别题目,我拿了 170,成功进入学校校队并排进了校队前三。
校队指导老师:icebin(武汉集训教练,但教的不是我所在的班)。
同时,我结交了志同道合的好友:Gu_Jiaxuanheyx0201zwz6666Hutao__

备战 CSP 2024(2024、8 ~ 2024、10)

这段时间,教练把 CSP-J 的内容快速的过了一遍,然后开始了繁琐的考前模拟,由于这次的目标是 CSP-J 一等,所以只考了 CSP-J 和初赛内容。
很遗憾,那时我没有做记录的习惯,但偶尔写写题解,我也是从这一时间段开始写题解的。

AT_abc176_e [ABC176E] Bomber(2024-08-31)

可以采用贪心的思路,用两个桶分别记录第 \(x\) 行、\(y\) 列上有多少个点,然后选取点数最多的那一条,然后相加得出答案。特别的,若两点相交处有一个点,点的总数就要减一,因为重复记录了。当然,若存在多种情况,自然选择相交处没有点的方案。

P10961 划分大理石(2024-09-14)

一道多重背包&刚好装满的简单背包问题。
先求大理石价值之和 \(c\),若 \(c\) 为奇数,则不可能组合出两对相同的价值和,直接输出 Can't,然后跳过即可。
然后直接套多重背包和刚好装满的板子就行了。

P5961 [BalticOI 2006] coin collector钱币收藏家(2024-09-15)

在读入数据的同时进行贪心求解。
根据题意,若已获面值总和大于枚举到的硬币,就需要取消购买最进一次购入的硬币,让面值总和小于枚举到的硬币的价值。在完成这一步之后进行下一步操作,如果这枚硬币还没有被收藏的话,购买它,若面值和大于收藏家的 \(K\) 分纸币,按照题意,算法结束。
对于硬币的购买记录,用一个栈储存,并记录购买的硬币个数。
最后如果面值总和为 \(0\) 的话,应输出 \(K - 1\)

P6332 [COCI 2007/2008 #1] PRINOVA(2024-09-15)

\(p_i\)\(p_{i+1}\) 间的所有答案中,越接近 \(\frac{p_i + p_{i+1}}{2}\) 的答案越优,因此,只需枚举 \(\frac{p_i + p_{i+1}}{2}\) 即可,若 \(\frac{p_i + p_{i+1}}{2}\) 为偶数,则需分别枚举 \(\frac{p_i + p_{i+1}}{2} +1\)\(\frac{p_i + p_{i+1}}{2} - 1\)
注意当 \(A \le p_{min}\)\(B \ge p_{max}\),还需拉出来单独计算一遍。

AT_abc137_e [ABC137E] Coins Respawn(2024-09-30)

题目给了我们一个有向图,不看支付金币的话,就是简单的跑最长路。但题目还需减去用时 \(T\)\(P\) 乘积,每走一步用时 \(1\) 分钟,可以看作一个步数,每走一步到了终点就要多付 \(P\) 枚硬币,由此边的权值就可以转化为:可获得的硬币数减去 \(P\) 所得到的差。
最后三点:一:若图中有正环且点 \(n\) 包含其中就不存在正确解,判环可以用 SPFA 实现,判断正环中是否包含 \(n\) 可以先从 \(n\) 开始逆向遍历整个图并记录所有 \(n\) 能抵达的点,让 SPFA 只枚举这些点;二:最后要进行判断,若解为负,输出 \(0\);三:由于数据较大,要开 long long。

SP2426 PLD - Palindromes(2024-10-03)

记录字符的长度,用 \(n\) 表示。用两个指针 \(l\)\(r\) 判断回文。
枚举字符串的第 \(k \div 2 -1\) 个字符到第 \(n - k \div 2 -1\) 个字符。若 \(k \bmod 2 = 1\)\(l\)\(r\) 从枚举的字符下标出发,背向而行;若\(k \bmod 2 = 0\)\(l\) 从枚举的字符下标出发,\(r\) 从下一个字符出发。比较 \(l\)\(r\) 访问到的字符,若不相等则不是回文,直接枚举下一个字符。若 \(l\)\(r\) 在其距离超过 \(k\) 且访问到的元素都相等,找到一个长度为 \(k\) 回文串。

AT_abc230_d [ABC230D] Destroyer Takahashi(2024-10-08)

先对所有的墙进行排序,以 \(r_i\) 大小为基准从升序排列,然后用一个变量 \(rs\) 记录破坏的范围。如果 \(l_i\le rs\),代表第 \(i\) 堵墙已经被破坏,反之没有,这就需要再打出一拳,答案数加一。直接线性枚举的时间复杂度为 \(O(n)\),可以通过此题,但仍可以继续优化,排序后的数据是有序的,不难想到用二分直接找到 \(l_i> rs\) 的墙,更新答案后继续查找,直到所有的墙都被破坏,算法结束。虽然时间复杂度仍为 \(O(n)\),但效率相对线性枚举更好。线性 VS 二分,效果十分明显。
时间主要花在排序上,总时间复杂度为 \(O(n\log n)\)

P11180 [ROIR 2018] 删除数字 (Day2)(2024-10-10)

很明显,每次删数只会删除 \(\lfloor \frac{n}{k} \rfloor\) 个数字,因此在满足 \(n\ge k\) 的情况下,让 \(n\) 减去 \(\lfloor \frac{n}{k} \rfloor\) 以模拟删数过程,并用一个计数器记录操作次数。当 \(n \bmod k =0\) 时,第 \(n\) 个数一定会被删掉,记录答案后打破循环即可。记录答案的变量初始化为 \(0\),如果第 \(n\) 个数不会被删除的话就不会被记录任何答案,输出的结果就是 \(0\),符合题意。
十年 OI 一场空,不开 long long 见祖宗 ~

AT_sumitb2019_f Interval Running(2024-10-19)

由公式 \(v=\frac{s}{t}\) 可得 \(s=vt\),现已知两个物体分两段运动,第一段两个物体运动的速度分别为 \(a_1\)\(b_1\) 以及运动时间 \(t_1\),第二段两个物体运动的速度分别 \(a_2\)\(b_2\) 以及运动时间 \(t_2\)
由此可得两段运动中两个物体的距离之差 \(s_1=(a_1-b_1)\times t_1\)\(s_2=(a_2-b_2)\times t_2\)

然后我们进行分类讨论:

  1. 第一种情况:\(s_1+s_2=0\)
    距离差为 \(0\) 代表两个物体相遇,而两段运动的距离差之和为 \(0\) 代表两段运动后这两个物体就刚好相遇,这就代表每进行两段运动就会相遇一次,也就一直可以相遇。

  2. 第二种情况:\(s_1\)\(s_2\) 都小于或大于 \(0\)
    出现这种情况代表两个物体在两段运动中的距离一直处于增加的状态,因此它们永远不可能相遇。

  3. 第三种情况:\(s_1<s_2\)\(|s_1|>s_2\)\(s_1>s_2\)\(|s_1|>-s_2\)
    物体一比物体二的速度永远快或慢,因此两个物体在两段运动中的距离也就一直处于非减少的状态,这种情况带来的后果和情况二相同,两个物体永远不可能相遇。

  4. 第四种情况:不满足以上情况的所有情况
    以第一次的第一段运动为基础,初始距离为 \(s\),以后的距离每相遇一次就会缩小 \(s_1-s_2\),当 \(s\) 缩小至小于等于 \(0\) 时,当前状况就变成了情况三或情况二了,就不会在出现相遇的情况了。因此很容易计算出其相遇的总次数为 \(\lfloor \frac{s_1}{s_1-s_2} \rfloor+1\)。 注意当 \(s_1 \bmod (s_1-s_2) =0\) 时代表 \(s\) 最终会变为 \(0\),因此这种情况相的相遇次数会比一般情况下少一,相遇次数为 \(\lfloor \frac{s_1}{s_1-s_2} \rfloor\)

由以上结论最终可得出一段极其简短的核心代码。

if(s1+s2==0) puts("infinity");//情况一 
else if((s1<0&&s2<0)||(s1>0&&s2>0)||(abs(s1)>(s1<0?s2:-s2))) puts("0");//情况二和三 
else write(abs(s1)%abs(s1+s2)==0?abs(s1)/abs(s1+s2)*2:abs(s1)/abs(s1+s2)*2+1);//情况四 

AT_abc177_c [ABC177C] Sum of product of pairs(2024-11-16)

这道题第一眼就是暴力,但数据明显超过了 \(O(n^2)\) 的能力范围,因此我们需要对代码进行优化。
根据伟大的乘法分配率,我们可以得出 \(\sum_{i=1}^{n-1}{\sum_{j=i+1}^{n}{a_i\times a_j}}\) 实际上就是 \(\sum_{i=1}^{n-1}{a_i\times \sum_{j=i+1}^{n}{a_j}}\)。因此,我们可以把求 \(\sum_{j=i+1}^{n}{a_j}\) 的过程优化成 \(O(1)\) 级别,这一过程可以通过前缀和实现,优化后的时间复杂度为 \(O(n)\),可以通过。

区间问题的学习(2024、11 ~ 2024、12)

一周一个内容,最后一周测试,太快了吧!不过还是简单拿捏~
完成内容:ST 表、树状数组、线段树应用、分块(自学)、主席树(自学)。

之后教练提倡我们写记录,我凑合着写了一点,不过大多是比赛赛题。

P11242 碧树(2024-11-02)

首先对数据a排序,然后枚举深度,发现 \(a_i\) 与枚举的深度相同,把它加入这个树。说白了,就是先建一条完全与 a 无关的链,长度为 max{a},发现 \(a_i\) 与枚举的深度相同,往这个链上增加结点。

P11279 「GFOI Round 2」Abstract String Basic(2024-11-16)

首先,遍历整个字符串,用一个数组记录每个字符出现的个数。然后,对 \(26\) 个字符的出现次数进行排序。最后,再次遍历整个字符串,由于 \(\tilde\psi(S,T)=\sum\limits_{i=1}^n\sum\limits_{j=1}^n[i\neq j][S_i\neq T_j]\)\(i \ne j\),遍历到的第 \(i\) 个字符不在统计范围内,所以该字符的实际个数在遍历到该字符的时候应减去一,如果它原本的字符在字符串中出现的次数与在字符串中出现次最少的字符相等,那么这个字符实际上才是使不相似度最大化的最优字符。反之,在字符串中出现次最少的字符才是使不相似度最大化的最优字符。

P11280 「GFOI Round 2」Jom & Terry(2024-11-16)

很明显,如果 Jom 从起点到根的距离小于 Terry 从起点到根的距离,那么 Jom 就可以先到达根,Terry 就绝对无法合法地到达根,因为题目已经说明了 Terry 不能走到 Jom 所在的结点。但是反之,由于 Terry 先手,如果 Terry 从起点到根的距离小于等于 Jom 从起点到根的距离,那么 Terry 就可以先到达根。这是最短路?图上边权全是 \(1\),因此直接 bfs 遍历图并记录从根到每个结点的最短距离即可。

P11308 茫茫的不归路(2024-11-23)

分类讨论题。
很明显,要想使每个营队的空间尽可能小,那么每个营队中就应分配 int(p/n) 人,那么,如果单个营队剩余空间小于k,Together。
如果连单个营队的所有空间都装不下k,Divide。
反之,Chance。

P11309 纷飞的樱花雨(2024-11-23)

贪心题,花了蛮长时间才把题康懂……
如果 \(k \ne 0\)\(n \ne 2\) 则有此贪心策略:把序列中的最大值交换到第一位,然后随意交换其余数,这样总和就为 n \(\times\) max{a}。
反之,如果 \(n=2\),就只能交换序列中的两个数,如果 \(n\bmod 2==0\),序列不变,反之,序列翻折。操作完后,按题意模拟即可。
\(k = 0\),无法进行任何操作,按题意模拟即可。

P11310 无穷的迭代器(2024-11-23)

虽然题目确实有典型的数学性质,但似乎可以直接暴力模拟。
注意一定不能用浮点数储存和模拟,原因只有一个:精度。
那怎么办?不难发现,在最开始 \(r\) 的值为 \(\frac{1+ 2\times k}{2}\),而且每次乘以 $ \lceil r \rceil $ 只会影响分子的值,也就是说,分母永远是 \(2\)
那么如果分子是偶数,那么该数就是整数,反之不是。因此只需令分子不断乘上 $ \lceil r \rceil $,直到该数为偶数为止。假设分子为 \(f\),则其相当于乘上 $ \lfloor \frac{f}{2} \rfloor +1$,因为 \(f\) 为奇数,所以上取整会进一。

那么复杂度呢?
我们进行一个分类讨论:

\(k\)\(0\),$ \lceil r \rceil $ 的值就永远是 \(1\),因此输出 NO!
如果 \(k\) 为奇数,那么 \(f\) 最开始也一定为奇数,因为奇数乘以偶数等于偶数,再加一个 \(1\) 就是奇数了。然后 $ \lfloor \frac{f}{2} \rfloor +1$ 的值一定为偶数,很明显,\(k\) 刚乘的一个 \(2\) 又被除掉了,因此得到的数是一个奇数加 \(1\) 的和,奇数加奇数等于偶数,没问题。所以就变为了一个奇数乘以一个偶数得到的结果一定是偶数,因此如果 \(k\) 为奇数那么只需进行一次操作就可以使其变为整数。
如果 \(k\) 为偶数,在操作过程中,它们在至多 \(\log_2 k\) 次操作后就变为一个奇数的两倍加一的值,因此时间复杂度满足题目要求。

P8287 「DAOI R1」Flame(2024-12-1)

用 bfs 模拟火焰蔓延,用并查集判简单环。为了维护正确性,每通过一条边访问一个结点,就把这条无向边删除。用一个数组记录点权,点权代表从初始结点到达某一结点的最短路径长度(边权为 \(1\))。

P11397 界分数(2024-12-14)

由爆搜套 gcd(25分)想到了记忆化搜套质数筛(65分),由记忆化搜想到了dp套线性筛(90分),最后通过 dp 打表找到了数学规律实现了 log 级别的算法(100分)

P11445 「ALFR Round 3」A 调皮的学生(2024-12-21)

直接用桶 \(f\) 计数即可,如果 \(f_i>1\) 代表 \(i\) 是一个调皮的学生,答案加一。

P11446 「ALFR Round 3」B Swap & Delete(2024-12-21)

直接对每种情况作分类讨论即可。
如果序列中存在两个及以上的相同数字就满足以下情况:

  • 1:如果第一个与最后一个相等,直接删除,只要进行一次操作
  • 2:如果第一个与第二个中有一个数在序列内部有相同的数,将其交换至另一侧,再删除,需两次操作。
  • 3:两个相同的数都在序列内部,则需将他们交换至开头与结尾再删除,需三次操作。
    最后如果序列中的元素互不相等,则需挨个删除每一个数,需 \(n\) 次操作。

AT_abc203_e [ABC203E] White Pawn(2024-12-29)

如果直接模拟肯定会炸,因为 \(N\) 的范围很大,因此还需进行离散化。枚举每行的黑子,统计该行同列的黑子和左上或左下的黑子后再统一进行转移。如果在统计过程中就进行转移会影响后续的统计,因此需全部统计完后再进行状态转移,也就是完成该行的删添。

寒假校队集训(2025-2-4 ~ 2025-2-9)

非常无聊啊,天天刷 AT 和 CF 的题。

AT_abc180_e [ABC180E] Traveling Salesman among Aerial Cities(2025-02-05)

典型的平面坐标 TSP 问题,由于数据范围不允许用搜索剪枝,因此考虑状压 dp,那么这就是一道板题了。
开两个维度,第一维表示压缩的状态,第二维表示到达某个城市的最短距离。易得转换方程:

\[dp_{s,i}=\min\{dp_{f(s,i),j}+cost(j,i)\} \]

其中 \(i,j\) 表示枚举的两个城市,\(cost(j,i)\) 表示题目要求的价值函数,\(f(s,i)\) 表示在压缩集合中访问的状态。
时间复杂度 \(O(2^n n^2)\),可以通过。

CF1873G ABBC or BACB(2025-02-07)

典型的线性 DP,先来考虑两个特殊情况:AAABBAAA
第一个情况可以变为 BCCC,获得 \(3\) 枚金币。第二个情况可以变为 CCCB,获得 \(3\) 枚金币。不难发现,当出现 \(k\)\(A\) 与一个 \(B\) 的组合,可通过操作一和二获得这 \(k\) 枚硬币。

我们可以通过遍历一遍字符串确定每一组连续的 \(A\) 子串的左边界,从而确定这一组的长度,用数组 \(l\) 储存下来,方便状态转移。
先建立一个 DP 数组 \(dp_{i,j}\),表示到第 \(i\) 个字符可获得的最大金币数,\(j\) 表示是否对第 \(i-1\)\(i\) 个字符形成的子串进行操作,\(0\) 表示不进行,\(1\) 表示进行。

随后分类讨论进行转移。

当第 \(i-1\)\(i\) 个字符形成的子串为 AB,即可获得 \(i-l_{i-1}\) 枚金币,可以由 \(dp_{l_{i-1}-1,0}\)\(dp_{l_{i-1}-1,1}\) 转换而来,从而得到转换方程:

\[dp_{i,1}=\max(dp_{l_{i-1}-1,0},dp_{l_{i-1}-1,1})+i-l_{i-1} \]

当第 \(i-1\)\(i\) 个字符形成的子串为 BA,由于 \(i\) 的限制,不能直接转移到连续 \(A\) 子串的右边界,因此只能获得一枚金币,然后用一个变量 \(c\) 记录下进行操作后第 \(i\) 个字符的变化,用于第三种情况。可得转换方程:

\[dp_{i,1}=dp_{i-1,0}+1 \]

\(c\)\(i\) 个字符形成的子串为 BA,表示上一次操作后可再进行一次操作,因此由 \(dp_{i-1,1}\) 转换而来,可得转换方程:

\[dp_{i,1}=dp_{i-1,1}+1 \]

最后的答案为 \(\max(dp_{n,0},dp_{n,1})\),其中 \(n\) 表示字符串末尾下标。

图论的学习(2025-3 ~ 2025-4)

三月学树,搞定了最近公共祖先、树的重心、直径。
四月学连通性问题,系统性的学完了点双,边双,强连通分量。
Tarjan 吃饱了。

其实这个入到五月末才搞懂了 Tarjan 算法……
太难了,没做任何记录。

动态规划的学习(2025-5 ~ 2025-6)

五月学完了树形、图上、数位、状压 DP,并在六月初的最后一次课上进行的测试,感觉除数位 DP 外掌握良好。

这段时间没想过做记录啊……连题解都断更了……

posted @ 2025-06-15 15:46  雨落潇湘夜  阅读(26)  评论(0)    收藏  举报
我的页脚图片