<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Qingw の Blog</title><description>ACM</description><link>https://qingw.top/</link><item><title>ACM笔记</title><link>https://qingw.top/posts/ACM%20notebook/</link><guid isPermaLink="true">https://qingw.top/posts/ACM%20notebook/</guid><description>ACM笔记</description><pubDate>Mon, 27 Apr 2026 20:32:00 GMT</pubDate><content:encoded>&lt;h2&gt;开头&lt;/h2&gt;
&lt;h3&gt;刷题的作用&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;知识点&lt;/li&gt;
&lt;li&gt;思维&lt;/li&gt;
&lt;li&gt;代码调试和实现&lt;/li&gt;
&lt;li&gt;前期：知识点 &amp;gt; 思维, 代码实现 &amp;gt; 代码调试&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;训练方案&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;提高难度，借助题解刷题&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;知识&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;有体系（自底向上）&lt;/li&gt;
&lt;li&gt;无体系（归纳法）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;数学&lt;/h2&gt;
&lt;h3&gt;异或&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CF2225D&lt;/strong&gt; 前缀异或和 $P(3mod4) = 0, P(1mod4) = 1$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;异或线性基&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给出一个数列 a1,a2,...,an，若一个序列 d1,d2,...,dk 满足以下性质：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有原数列中的元素能够异或出来的值 d 中的数也能异或出来&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;d[i]&lt;/code&gt;中非零的个数就是这个线性空间的秩(线性无关的向量的个数)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P3812&lt;/strong&gt;  最大值问题 从高位到低位贪心异或&lt;/li&gt;
&lt;li&gt;最小值问题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;hdu3949&lt;/strong&gt;第k小问题: 净化后的p数组, 二进制拆分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P3857&lt;/strong&gt;异或和问题 $2^k\k为d[i]非零的个数$&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P4570&lt;/strong&gt; 贪心插入元素,动态查看能否被消掉 (极大线性无关组的个数是常数(秩))&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;鸠巢原理&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;有N + 1个可能， 但是只有N个抽屉， 那么必然至少有一个会有重复的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;200_D&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;质数筛&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;任何一个合数都是可以整除比他小的一个质数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P5440&lt;/strong&gt; 要判断一个数是否是质数， 就要看$\sqrt{N}$的范围里的质数能不能整除&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;412_E&lt;/strong&gt; 区间筛法， 用小筛子去筛大数, 对于每个小质数， 乘以 倍数后把[L,R]里的合数筛掉,剩下的就一定是质数&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;矩阵加速&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;斐波那契 &lt;strong&gt;POJ-3070&lt;/strong&gt;
$$
\begin{pmatrix}
F_n F_{n-1}
\end{pmatrix}
\begin{bmatrix}
1&amp;amp;1\
1 &amp;amp;0\
\end{bmatrix}
$$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;POJ-3233&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;$$
\begin{pmatrix}
A_k&amp;amp;S_k
\end{pmatrix}
\begin{bmatrix}
A&amp;amp;A\
0&amp;amp;1\
\end{bmatrix}&lt;/h1&gt;
&lt;p&gt;\begin{pmatrix}
A_{k+1}&amp;amp;S_{k+1}
\end{pmatrix}
$$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P1306&lt;/strong&gt; $gcd(f_i, f_j) = f_{gcd(i, j)}$ 斐波那契数列最大公因数性质&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;斐蜀定理&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;两个互质的数a和b&lt;/p&gt;
&lt;p&gt;凑不出的最大整数为$S = a * b - a - b$, 在S之后的数都可以用a 和 b凑出来（用于路径压缩）， 所以大于S的路径直接变成S长度&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;路径压缩 &lt;strong&gt;P1052&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;概率论&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;逆元的计算（费马小定理（$n ^ {p-2}$ 前提是p是质数）， 扩展欧拉函数）： 适用于求单点的逆元&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;逆元的预处理 （阶乘预处理， 再处理逆元） ： 适用于大范围的逆元&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;模类Z&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;组合数$C_n^m = \frac{n!}{m!(n-m)!}$&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;计算几何&lt;/h3&gt;
&lt;h4&gt;扫描线&lt;/h4&gt;
&lt;h2&gt;动态规划&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;定义dp数组 -&amp;gt; 初始化dp数组 -&amp;gt; 转移方程&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;DP数组的初始化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;求方案数（初始化为-1）来看看是否算过&lt;/li&gt;
&lt;li&gt;求最小值（初始化为1E9）&lt;/li&gt;
&lt;li&gt;求最大值（初始化为-1E9）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;线性DP&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;dp数组的思考 : 有足够的信息, 不会破坏无后效性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;二维dp  &lt;strong&gt;P2758&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;带状态的dp &lt;strong&gt;P1541&lt;/strong&gt;乌龟棋&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;abc_418D&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;最长递增子序列&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;tails数组 --&amp;gt; tails[1] = 7 代表长度为2的LIS的最小结尾数字为7
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P1020&lt;/strong&gt; 找&lt;code&gt;&amp;lt;=&lt;/code&gt; 序列用 &lt;code&gt;upper_bound(&amp;gt;)&lt;/code&gt;， 找&lt;code&gt;&amp;lt;&lt;/code&gt;序列用 &lt;code&gt;lower_bound(&amp;gt;=)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;树上DP&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;套路： 父节点的&lt;strong&gt;全集信息&lt;/strong&gt;需要靠子节点的&lt;strong&gt;全集信息&lt;/strong&gt;递归来返回&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;例题&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;树上背包&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.luogu.com.cn/problem/P12136&quot;&gt;P12136&lt;/a&gt;  &lt;code&gt;dp[u][val]&lt;/code&gt;定义为u能否凑出val的重量&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.luogu.com.cn/problem/P1273&quot;&gt;P1273&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;**P201&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;树上DP&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.luogu.com.cn/problem/P1352&quot;&gt;P1352&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.luogu.com.cn/problem/P1122&quot;&gt;P1122&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P2607&lt;/strong&gt; 基环树&quot;森林&quot; --&amp;gt; 多个连通块，但每个连通块都只有一个基环树(一个环，环上的节点可以形成树)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P3177&lt;/strong&gt; 树上染色 -- 边的贡献&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;数位DP&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;利用条件判断加递归&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;技巧&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;利用转字符串来的到数字的某一位&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例题&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;P2602&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;状压DP&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;dp[status][i]&lt;/code&gt; status == (1 &amp;lt;&amp;lt; MAXN)， 用位来表示每一个东西已经选了或者还没选(状态的子集状态)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;例题
&lt;ul&gt;
&lt;li&gt;旅行商问题 P1433 P1171 列举mask从小到大&lt;/li&gt;
&lt;li&gt;棋盘问题 P1896  P2704&lt;/li&gt;
&lt;li&gt;老鼠吃奶酪 P1433&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;区间DP&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;小区间合并成大区间&lt;/p&gt;
&lt;p&gt;一般允许$$O(n^3)$$的复杂度&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;[数字游戏]:(http://10.160.111.129/p/2873&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;P1775&lt;/strong&gt; 石子合并&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;0-1背包&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;两个变量: 容量和价值， 依次遍历每个物品，更新dp[容量] = std::max(价值1， 价值2)， dp[i]数组定义是在容量为x的时候最大价值是多少， 可以买或者不买来更新&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;410_E&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1776&lt;/strong&gt; 0-n背包(需要打包操作, 要从小到大的打包)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;数据结构&lt;/h2&gt;
&lt;h3&gt;链表&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P1996&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1160&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;带版本控制的链表(可持久化)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;411_D&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;前缀和 差分&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;二维前缀和公式 : &lt;code&gt;a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;二维差分公式: &lt;code&gt;d[x1][y1]++, d[x1][y2 + 1]--, d[x2 + 1][y1]--, d[x2 + 1][y2 + 1]++&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;410E&lt;/strong&gt; 二维前缀和&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;abc_419D&lt;/strong&gt; 差分数组&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;BIT&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;a[0011] 代表以3结尾，长度为1的区间和, a[0100]代表以4结尾，长度为4的区间和&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;维护可差分（可减性）信息（由两个大区间得到一个小区间）&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;单点修改 + 区间查询（维护原数组） &lt;strong&gt;P3374&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;求逆序对 &lt;strong&gt;P1774&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;树上逆序对 &lt;strong&gt;P3605&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;离线查询 + 维护区间出现了几次  &lt;strong&gt;P1972&lt;/strong&gt; &lt;strong&gt;P4113&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;单点查询 + 区间修改（维护差分数组）&lt;strong&gt;P3368&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;区间查询 + 区间修改 （维护D和Di）&lt;strong&gt;P3372&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;二维数组 + 单点修改 + 区间查询 （维护二维数组）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;二维数组 + 区间修改 + 区间查询 （维护二维差分数组）&lt;strong&gt;P4514&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;DSU&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;408_E&lt;/strong&gt; :求两点之间最小OR路径， 维护连通性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bailian-1182&lt;/strong&gt; **P1525 **拓展域并查集&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;hdu3038&lt;/strong&gt; &lt;strong&gt;hdu3635&lt;/strong&gt;带权并查集, 相对位置...&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P4185&lt;/strong&gt; 并查集加离线海量查询&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P2294&lt;/strong&gt; 带权并查集&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;RMQ&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;对数组的范围静态查询， （最大值， 最小值， 最大公约数）&lt;/p&gt;
&lt;p&gt;$$rmq[i][k]$$ 可以理解成管辖[i, i + (1 &amp;lt;&amp;lt; k))的一个值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;倍增思想： 就是很大的区间分成一个较大的区间，然后剩下的区间再递归... &lt;strong&gt;P4155&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;线段树&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;区间查询 + 区间修改 + 一维数组 + （有组合律）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P3372&lt;/strong&gt; 区间和&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P13825&lt;/strong&gt; 动态开点线段树&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;单调栈&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;找到阶段性的强者&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;例题
&lt;ul&gt;
&lt;li&gt;动态后缀最大值 &lt;strong&gt;P1198&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;求全0矩形的方案 &lt;strong&gt;P1950&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;求最大全0矩形 &lt;strong&gt;P4147&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;单调队列/滑动窗口&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;与普通的队列不同的是，这是一个双端队列&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P1886&lt;/strong&gt; 求一个窗口内的的最大值, 最小值&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1714&lt;/strong&gt; 求不定长子段最大和（前缀和 + 滑动窗口）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P3957&lt;/strong&gt; 二分答案 + [L, R]的单调队列 + 坐标离散&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1419&lt;/strong&gt; 二分答案 + [L, R]的单调队列 + 前缀和&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;堆/优先队列&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;自动维护最小值，最大值， 反悔贪心的关键数据结构&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;LCA（最近公共父节点）&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;作用：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;求树上两点的距离&lt;/li&gt;
&lt;li&gt;树上差分（点差分[diff[u]++,diff[v]++,diff[lca]--, diff[fa[lca]]]--，边差分 diff[u]++,diff[v]++,diff[lca]-2)&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P3379&lt;/strong&gt; 模板&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P2680&lt;/strong&gt; , &lt;strong&gt;P9246&lt;/strong&gt;边差分&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;算法&lt;/h2&gt;
&lt;h3&gt;搜索&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;每个节点都是状态(位置， 颜色......), 我们需要找到一条从起点到终点的有效边&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;暴力搜索 -&amp;gt; 剪枝叶(处理无效状态)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;P5294&lt;/li&gt;
&lt;li&gt;P1118  一维上的， 从左到右选数问题&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;暴力搜索 -&amp;gt; 开dp数组(处理重复问题)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;折半搜索(用空间换时间), 先把前半部分的结果存起来(DFS)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;适用于一维上的选和不选求子集和, 然后$2^N会TLE但是2^{N/2}不会的数据范围$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;时间: $2^N\to2^{N/2}+2^{N/2}\times log(2^{N/2})$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;空间: $0 \to 2^{N/2}$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;P3067&lt;/strong&gt; 折半搜索 + 掩码（表示集合状态）+ vector排序去重替代set&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;P4799&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;P5195&lt;/strong&gt; 两段BFS&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IDA*（带有深度限制的， 带有估价函数剪枝的DFS)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;适用范围是: 状态的分支太多会爆队列, 却要求最小步数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;POJ3134&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;分治法&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;把大问题分成两半， 再递归合并&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P1908&lt;/strong&gt; 分治求逆序对&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P3806&lt;/strong&gt; 点分治&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;CDQ分治&lt;/h4&gt;
&lt;h3&gt;倍增&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P3509&lt;/strong&gt; 滑动窗口 + 倍增跳跃&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;图论&lt;/h3&gt;
&lt;h4&gt;DFS&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;父节点给子节点初始化信息， 先操作，后递归&lt;/p&gt;
&lt;p&gt;子节点给父节点更新消息，先递归， 后操作&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;417E&lt;/strong&gt; 派出一个哨兵来给我信息这条路可能通终点吗&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;BFS&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;多源BFS  ABC_405_D&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;洪水填充&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P1162&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1506&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;二分图&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;​&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;二分图最大匹配（匈牙利算法）: 二分图中每条边都是一对一的（没有公共节点）&lt;strong&gt;P3386&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;哈夫曼树&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;高频短码， 低频长码， 从底至上&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P1090&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P2168&lt;/strong&gt; K分支哈夫曼树， 要挂空节点保证最后剩一个&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;dji算法&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;优先队列维护的是&lt;strong&gt;全局&lt;/strong&gt;的最近的点&lt;/p&gt;
&lt;p&gt;算法复杂度 $O(N + M)log(N)$  N+M是遍历了图中的所有点和边, logN是优先队列比较每个点&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P3956&lt;/strong&gt; 带颜色状态的Dij算法&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1126&lt;/strong&gt; 机器人搬货物，要判断合法状态&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;[L2-001]&lt;/strong&gt;(https://pintia.cn/problem-sets/994805046380707840/exam/problems/type/7?problemSetProblemId=994805073643683840&amp;amp;page=1)dji模板加路上的状态维护&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P2865&lt;/strong&gt; 求次短路径(维护dist1和dist2, 一个最短一个次短)--&amp;gt; 拓展K短路（暂时不学）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1266&lt;/strong&gt; 分层图dij, 带一个速度状态的dij&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P5304&lt;/strong&gt; 多源dij + 染色法, 用于求某个点距离该集合最近的距离和点&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;floyd&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;求全局任意两点的最短路, $O(n^3)$&lt;/p&gt;
&lt;p&gt;剪枝很重要， 很有可能不剪枝过不了&lt;strong&gt;hdu_1704&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;// abc_416_E 动态增加新路 O(n^2)
dist[i][j] = std::min({dist[i][j],
                       dist[i][x] + dist[x][y] + dist[y][j],
                       dist[i][y] + dist[y][x] + dist[x][j]});
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;hdu_1385&lt;/strong&gt; floyd维护最短路径(1-&amp;gt;2-&amp;gt;3...)，利用&lt;code&gt;nxt[i][j]&lt;/code&gt;数组, 拓展: nxt[i]可以用于dijiskra算法的单源最短路径&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1119&lt;/strong&gt; 按照时间顺序来写中转点来更新dist&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1913&lt;/strong&gt; floyd前要先倍增建图&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;hdu_1704&lt;/strong&gt; 把&lt;code&gt;dist[i][j]&lt;/code&gt;想成i和j的关系, 他们之间可以通过中转点K来确定另一个关系,统计答案的时候不要重复统计&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P1730&lt;/strong&gt; 初始化floyd的时候多加一个维度&lt;code&gt;f[i][j][k]&lt;/code&gt;表示i到j经过了k条边的最大路径和&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;spfa&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;用来判断图中是否有负环,初始的时候要把所有点入队(防止图不连通), 所有dist都为0&lt;/p&gt;
&lt;p&gt;如果没有负环, 起始节点到目标节点的走过的边数应该是&amp;lt;= V - 1(整个图的总点数)&lt;/p&gt;
&lt;p&gt;如果是从0号点出发,则其他的dist应该为INF(这种是求最短路顺便判断负环)&lt;/p&gt;
&lt;p&gt;算法复杂度: 最坏是$O(NM)$ 菊花图&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P5960&lt;/strong&gt; 差分约束，判断负环存在&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P2868&lt;/strong&gt; 二分计算边的权重，spfa判负环&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P3385&lt;/strong&gt; 单点可到达的负环&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P2294&lt;/strong&gt; 差分约束&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;johnson&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;求全源最短路 $O(NMlog(M))$&lt;/p&gt;
&lt;p&gt;先用spfa求势能,再跑n个dij算法&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P5905&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;tarjan&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;SCC: 强连通分量, 一个&lt;strong&gt;有向子图&lt;/strong&gt;(不是树)中任意两个点连通&lt;/p&gt;
&lt;p&gt;$dfn_n$: dfs顺序遍历的编号&lt;/p&gt;
&lt;p&gt;$low_n$ : u为根的&lt;strong&gt;子树&lt;/strong&gt;的所有节点能够到达的最小dfn序&lt;/p&gt;
&lt;p&gt;割边: 如果删掉这条边, 图中的连通块(分量)变多&lt;/p&gt;
&lt;p&gt;割点: 如果删掉这个点, 图中的连通块(分量)变多&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;割边 &lt;strong&gt;P1656&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;割点 &lt;strong&gt;P3388&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;字符串&lt;/h3&gt;
&lt;h4&gt;马拉车&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;解决回文问题&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;KMP&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;找到S1中的S2的位置 , $S_2 \in S_1$&lt;/p&gt;
&lt;p&gt;$nxt$数组是在[0, i)的前缀中的最长公共前后缀&lt;/p&gt;
&lt;p&gt;$n-nxt[n] == x$ 则$s[i] == s[i+x]$ 则x为最小循环字串的大小&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;字符串哈希&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;判断字符串是否相等&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;字典树（前缀树）&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;记录多个字符串的前缀&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;维护字符串的字典树&lt;/li&gt;
&lt;li&gt;0-1 Trie 求路径最大异或和 P4551&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;杂项&lt;/h2&gt;
&lt;h3&gt;CF思考角度&lt;/h3&gt;
&lt;h4&gt;从局部思考推到整体&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CF2225B&lt;/strong&gt; 把l和r影响的是局部和其他, 内部不影响, 外部最后影响两个冲突&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;旋转操作&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;顺时针90° $(i, j) \to (j, N-1-i)$&lt;/li&gt;
&lt;li&gt;逆时针90°$(i, j) \to (N-1-j,i)$&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;// 顺时针
vector&amp;lt;string&amp;gt; ns(n);
for (int i = N - 1; i &amp;gt;= 0; --i) {
    for (int j = 0; j &amp;lt; N; ++j) {
        ns[j] += s[i][j]; 
    }
}
// 从最后一行向上从左到右发牌
// 1 2 3       7 4 1
// 4 5 6 ====&amp;gt; 8 5 2
// 7 8 9       9 6 3

// 逆时针
vector&amp;lt;string&amp;gt; ns(n);
for (int i = 0; i &amp;lt; N; ++i) {
    for (int j = 0; j &amp;lt; N; ++j) {
        ns[N - 1 - j] += s[i][j];  
    }
}

// 
// 1 2 3      3 6 9
// 4 5 6 ===&amp;gt; 2 5 8
// 7 8 9      1 4 7
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;位运算&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// 取一位数n的最高位1的位置
int high_bit = 63 - __builtin_clzll(n);
// 制作一个数前i位都是1 (11111100000)
-(1 &amp;lt;&amp;lt; i) + 1;
// 取一个数的最小的一位1
x &amp;amp; -x
// 取x的第i位
(x &amp;gt;&amp;gt; i) &amp;amp; 1
// 取反x的第i位
x ^= (1 &amp;lt;&amp;lt; i)
// 将x的第i位取0
x &amp;amp;= ~(1 &amp;lt;&amp;lt; i)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;408E&lt;/strong&gt; 通过贪心求最小或和&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;贪心&lt;/h3&gt;
&lt;h4&gt;反悔贪心&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;在一维数组上进行要或者不要（这个值）， 带有前缀条件，用优先队列&lt;/p&gt;
&lt;p&gt;先无脑入队列&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;例题
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc407/tasks/abc407_e&quot;&gt;407_e&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;**P30&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;最大子段和&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Kadane 算法 ： 通过维护历史最值来判断是继续加，还是清零&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;普通的Kadane算法&lt;strong&gt;P1719&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;环形Kadane算法**P1121*&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;破环成链&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P2629&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P4155&lt;/strong&gt; 断环成链后， 寻找覆盖区间超过环的连续区间就OK了&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;如何调代码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
#define _CLR_CYAN   &quot;\033[1;36m&quot;
#define _CLR_GREEN  &quot;\033[1;32m&quot;
#define _CLR_RESET  &quot;\033[0m&quot;
using i64 = long long;
using i128 = __int128;
inline std::ostream&amp;amp; operator&amp;lt;&amp;lt;(std::ostream&amp;amp; os, __int128 n) {
    if (n == 0) return os &amp;lt;&amp;lt; &quot;0&quot;;
    if (n &amp;lt; 0) { os &amp;lt;&amp;lt; &quot;-&quot;; n = -n; }
    std::string s;
    while (n &amp;gt; 0) { s += (char)(&apos;0&apos; + (n % 10)); n /= 10; }
    std::reverse(s.begin(), s.end());
    return os &amp;lt;&amp;lt; s;
}

template &amp;lt;typename T&amp;gt;
void dbg_out(const T&amp;amp; val) { std::cerr &amp;lt;&amp;lt; val; }

template &amp;lt;typename A, typename B&amp;gt;
void dbg_out(const std::pair&amp;lt;A, B&amp;gt;&amp;amp; p) { std::cerr &amp;lt;&amp;lt; &apos;(&apos; &amp;lt;&amp;lt; p.first &amp;lt;&amp;lt; &quot;, &quot; &amp;lt;&amp;lt; p.second &amp;lt;&amp;lt; &apos;)&apos;; }

template &amp;lt;typename T&amp;gt;
requires requires(T t) { t.begin(); t.end(); }
void dbg_out(const T&amp;amp; v) {
    std::cerr &amp;lt;&amp;lt; &apos;[&apos;;
    bool first = true;
    for (const auto&amp;amp; x : v) {
        if (!first) std::cerr &amp;lt;&amp;lt; &quot;,&quot;;
        first = false;
        dbg_out(x);
    }
    std::cerr &amp;lt;&amp;lt; &apos;]&apos;;
    std::cerr &amp;lt;&amp;lt; &quot;Total:&quot; &amp;lt;&amp;lt; v.size() &amp;lt;&amp;lt; &apos;\n&apos;;
}
template &amp;lt;typename T, std::size_t N&amp;gt;
void dbg_out(const T (&amp;amp;a)[N]) {
    std::cerr &amp;lt;&amp;lt; &apos;[&apos;;
    for (std::size_t i = 0; i &amp;lt; N; ++i) {
        if (i &amp;gt; 0) std::cerr &amp;lt;&amp;lt; &quot;,&quot;;
        dbg_out(a[i]);
    }
    std::cerr &amp;lt;&amp;lt; &quot;]&quot;;
    std::cerr &amp;lt;&amp;lt; &quot;Total:&quot; &amp;lt;&amp;lt; N &amp;lt;&amp;lt; &apos;\n&apos;;
}
template &amp;lt;typename T&amp;gt;
requires requires(T t) { t.begin(); t.end(); }
void dbg_out_range(const T&amp;amp; v, int L, int R) {
    std::cerr &amp;lt;&amp;lt; &apos;[&apos;;
    bool first = true;
    auto it = std::next(v.begin(), L);
    for (int i = L; i &amp;lt; R &amp;amp;&amp;amp; it != v.end(); ++i, ++it) {
        if (!first) std::cerr &amp;lt;&amp;lt; &quot;,&quot;;
        first = false;
        dbg_out(*it);
    }
    std::cerr &amp;lt;&amp;lt; &quot;]&quot;;
    std::cerr &amp;lt;&amp;lt; &quot;Range: [&quot; &amp;lt;&amp;lt; L &amp;lt;&amp;lt; &quot;, &quot; &amp;lt;&amp;lt; R &amp;lt;&amp;lt; &quot;), Total: &quot; &amp;lt;&amp;lt; v.size() &amp;lt;&amp;lt; &apos;\n&apos;;
}
template &amp;lt;typename T, std::size_t N&amp;gt;
void dbg_out_range(const T (&amp;amp;a)[N], int L, int R) {
    std::cerr &amp;lt;&amp;lt; &apos;[&apos;;
    for (int i = L; i &amp;lt; R &amp;amp;&amp;amp; i &amp;lt; (int)N; ++i) {
        if (i &amp;gt; L) std::cerr &amp;lt;&amp;lt; &quot;,&quot;;
        dbg_out(a[i]);
    }
    std::cerr &amp;lt;&amp;lt; &quot;]&quot;;
    std::cerr &amp;lt;&amp;lt; &quot;Range: [&quot; &amp;lt;&amp;lt; L &amp;lt;&amp;lt; &quot;, &quot; &amp;lt;&amp;lt; R &amp;lt;&amp;lt; &quot;), Total: &quot; &amp;lt;&amp;lt; N &amp;lt;&amp;lt; &quot;\n&quot;;
}
#define debug(x) \
    std::cerr &amp;lt;&amp;lt; _CLR_CYAN &amp;lt;&amp;lt; &quot;[&quot; &amp;lt;&amp;lt; #x &amp;lt;&amp;lt; &quot;]&quot; &amp;lt;&amp;lt; _CLR_RESET &amp;lt;&amp;lt; &apos;\n&apos;; \
    std::cerr &amp;lt;&amp;lt; _CLR_GREEN; dbg_out(x); std::cerr &amp;lt;&amp;lt; _CLR_RESET &amp;lt;&amp;lt; &apos;\n&apos;;

#define debug_range(x, L, R) \
    std::cerr &amp;lt;&amp;lt; _CLR_CYAN &amp;lt;&amp;lt; &quot;[&quot; &amp;lt;&amp;lt; #x &amp;lt;&amp;lt; &quot;]&quot; &amp;lt;&amp;lt; _CLR_RESET &amp;lt;&amp;lt; &apos;\n&apos;; \
    std::cerr &amp;lt;&amp;lt; _CLR_GREEN; dbg_out_range(x, L, R); std::cerr &amp;lt;&amp;lt; _CLR_RESET &amp;lt;&amp;lt; &apos;\n&apos;;

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;int 与 int 相乘 会溢出， 应该转为i64&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;字符串的stl操作&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;string text;
text.find(word, pos) // ==&amp;gt; string::npos;
text.replace(pos, len, str)

    // 输入
    std::cin // 会留下一个换行符, 忽略空格换行符
    std::cin.ignore(); // 吃掉一个字符
    std::cin.get(c)
    std::getline(std::cin, s); // 读取,直到换行符,会吃掉换行符

	// 标准流程(读取多行字符串)是
	int n;
	std::cin &amp;gt;&amp;gt; n;

	// 坚决清空第一行数字后面的所有残留物
	std::string dummy;
    std::getline(std::cin, dummy); 

    for (int i = 0; i &amp;lt; n; ++i) {
        std::string s;
        std::getline(std::cin, s); // 干净清爽地读取每一行
        // 处理字符串 s ...
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;天梯赛的阴函数&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// 补全前导零
os &amp;lt;&amp;lt; std::setfill(&apos;0&apos;) // 全局有效i
os &amp;lt;&amp;lt; std::setw(5) // 只对后面一个数有效
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;sort的元素满足传递性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P2123&lt;/strong&gt; 中我们可以通过sgn(x) 来比较 $min(a_1,b_2) 与 min(a_2, b_1)$,&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;较难知识点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ABC_454G --&amp;gt; DSU on tree&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>Codeforces</category><author>Qingw</author></item><item><title>不想更新了</title><link>https://qingw.top/posts/talks/</link><guid isPermaLink="true">https://qingw.top/posts/talks/</guid><description>不想更新了 题解与思路分析</description><pubDate>Sat, 17 Jan 2026 19:07:00 GMT</pubDate><content:encoded>&lt;p&gt;OK呀， 本人感觉更新太费时间了，准备停止更新&lt;/p&gt;
</content:encoded><category>杂谈</category><author>Qingw</author></item><item><title>Hello2026</title><link>https://qingw.top/posts/Hello2026/</link><guid isPermaLink="true">https://qingw.top/posts/Hello2026/</guid><description>Hello2026 题解与思路分析</description><pubDate>Thu, 08 Jan 2026 14:08:00 GMT</pubDate><content:encoded>&lt;p&gt;import ProblemCard from &apos;../../components/ProblemCard.astro&apos;;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;新年第一赛ABC做了, 记录一下&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
link=&quot;https://codeforces.com/contest/2183/problem/A&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;A Binary Array Game&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目概述&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;给你一个数组$a$, 这个数组$a$里只有0和1&lt;/p&gt;
&lt;p&gt;Alice和Bob可以执行两个操作之一, Alice先走&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选择$a_l$到$a_r$删除并替换为一个数字$1 - min(a_l...a_r)$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;求谁会赢?（只剩下一个数字，如果是0 Alice赢， 如果是1 Bob赢&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;题目分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;只要$a_l-a_r$有0, 替换后就为1&lt;/p&gt;
&lt;p&gt;Alice想赢就得把数组变为全1&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;起始数组为11111111， 那么Alice赢&lt;/li&gt;
&lt;li&gt;起始数组为1xxxxxxxx,  因为x中有0， 所有我们选择$a_2, a_n$， 就变成了11 Alice赢&lt;/li&gt;
&lt;li&gt;起始数组为xxxxxxxx1， 选择$a_1, a_{n-1}$, 就变成了11 Alice赢&lt;/li&gt;
&lt;li&gt;起始数组为0xxxxxxx0, Alice操作后肯定是0xxxxxxx, Bob直接选择$a_2, a_n$ 就变成了1 Bob赢&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;const int MAXN = 101;
int a[MAXN];
void solve() {
    int n; cin &amp;gt;&amp;gt; n;
    for (int i = 1; i &amp;lt;= n; ++i) {
        cin &amp;gt;&amp;gt; a[i];
    }
    if (a[1] || a[n]) cout &amp;lt;&amp;lt; &quot;Alice\n&quot;;
    else cout &amp;lt;&amp;lt; &quot;Bob\n&quot;;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
link=&quot;https://codeforces.com/contest/2183/problem/B&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;B&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目概述&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;给你一个数组$a$， 长度$n$， 一个窗口长度为$k$， $f(l,r) = mex(a_l, a_r)$&lt;a href=&quot;Mex%E6%98%AF%E6%9C%80%E5%B0%8F%E7%9A%84%E6%9C%AA%E5%87%BA%E7%8E%B0%E7%9A%84%E6%AD%A3%E6%95%B4%E6%95%B0&quot;&gt;^1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;你每次选择$mex$最大的窗口并且在这个窗口里删除一个数&lt;/p&gt;
&lt;p&gt;求最后$a$只剩$k-1$长度时， 最大的$mex(a)$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;题目分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;我们需要尽可能保护$a$中的$0,1,2...k-2$&lt;/p&gt;
&lt;p&gt;答案为$max(mex(a), k-1)$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;const int MAXN = 2e5 + 1;
int a[MAXN];
void solve() {
    int n, k; cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; k;
    for (int i = 1; i &amp;lt;= n; ++i) {
        cin &amp;gt;&amp;gt; a[i];
    }
    sort(a + 1, a + 1 + n);
    int e = unique(a + 1, a + 1 + n) - a - 1;
    int ans = e;
    for (int i = 1; i &amp;lt;= e; ++i) {
        if (i - 1 != a[i]) {
            ans = i - 1;
            break;
        }
    }
    ans = min(k - 1, ans);
    cout &amp;lt;&amp;lt; ans &amp;lt;&amp;lt; endl;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
link=&quot;https://codeforces.com/contest/2183/problem/C&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;C War Strategy&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目概述&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;给n,m,k&lt;/p&gt;
&lt;p&gt;n代表数组长度， m代表限制天数， k代表起始大本营&lt;/p&gt;
&lt;p&gt;每天可以执行操作&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a_i的士兵部分或全部的移动一个单位&lt;/li&gt;
&lt;li&gt;a_k的士兵加1&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;问在m天内，怎么让数组上士兵不为空的格子最多?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;题目分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;我们先分析拓展一边&lt;/p&gt;
&lt;p&gt;$3, \underbrace{2,1}&lt;em&gt;{d_2 = 2}0 \underbrace{1,2,3}&lt;/em&gt;{d1=3}$&lt;/p&gt;
&lt;p&gt;其中0代表大本营, 我们怎么让给定d1， 使得运输的时间最短?-- 当然是先屯兵，再一起走&lt;/p&gt;
&lt;p&gt;$t_{d_1} = t_{屯兵} + t_{行军}= d_1 + d_1 - 1 =2d_1-1$&lt;/p&gt;
&lt;p&gt;我们发现了一件事情, 在行军的过程中大本营也在屯兵&lt;/p&gt;
&lt;p&gt;$t_{d_2} = t_{屯兵} + t_{行军} = max(0, d_2 - d_1) + 1 + d_2 - 1 == max(0, d_2-d_1)+d_2$&lt;/p&gt;
&lt;p&gt;可得:&lt;/p&gt;
&lt;p&gt;$t_d = t_{d_1} + t_{d_2} = 2d_1 + d_2 - 1 + max(0, d_2-d_1)$&lt;/p&gt;
&lt;p&gt;我们定$d_2 &amp;lt; d_1$ 则$t_d = 2d_1 + d_2 - 1$&lt;/p&gt;
&lt;p&gt;为了让$t_d\leq m &amp;amp; d_1 + d_2最大$&lt;/p&gt;
&lt;p&gt;我们要让$d_2$尽可能大，看循环部分的代码&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;int n, m, k;
void solve() {
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m &amp;gt;&amp;gt; k;
    int mx = max(k - 1, n - k);
    int mn = min(k - 1, n - k);
    int ans = 0;
    for (int d2 = 0; d2 &amp;lt;= mn; ++d2) {
        for (int d1 = mx; d1 &amp;gt;= d2; --d1) {
            if (d2 + 2 * d1 - 1 &amp;lt;= m) {ans = max(ans, d1 + d2 + 1); break;}
        }
    }
    cout &amp;lt;&amp;lt; ans &amp;lt;&amp;lt; endl;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
link=&quot;https://codeforces.com/contest/2183/problem/D1&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
link=&quot;https://codeforces.com/contest/2183/problem/D2&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Codeforces</category><author>Qingw</author></item><item><title>rt1500</title><link>https://qingw.top/posts/rt1500/</link><guid isPermaLink="true">https://qingw.top/posts/rt1500/</guid><description>rt1500 题解与思路分析</description><pubDate>Sun, 04 Jan 2026 20:55:00 GMT</pubDate><content:encoded>&lt;p&gt;import ProblemCard from &apos;../../components/ProblemCard.astro&apos;;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/contest/1526/problem/C1&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/contest/1538/problem/F&quot;
/&amp;gt;
&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/contest/1522/problem/B&quot;
/&amp;gt;
&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/contest/1516/problem/B&quot;
/&amp;gt;
&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/contest/1542/problem/B&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Codeforces</category><author>Qingw</author></item><item><title>个签</title><link>https://qingw.top/posts/Biography/</link><guid isPermaLink="true">https://qingw.top/posts/Biography/</guid><description>个签</description><pubDate>Sat, 03 Jan 2026 23:04:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;随风潜入夜&lt;/li&gt;
&lt;li&gt;可乐&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>杂谈</category><author>Qingw</author></item><item><title>nvim快捷键</title><link>https://qingw.top/posts/nvimShortcut/</link><guid isPermaLink="true">https://qingw.top/posts/nvimShortcut/</guid><description>nvim快捷键</description><pubDate>Sat, 03 Jan 2026 18:13:00 GMT</pubDate><content:encoded>&lt;h2&gt;回退时间撤销&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;:earlier 10s
:earlier 10m
:later 10m
:later 10s
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><category>杂谈</category><author>Qingw</author></item><item><title>rt1400</title><link>https://qingw.top/posts/rt1400/</link><guid isPermaLink="true">https://qingw.top/posts/rt1400/</guid><description>rt1400 题解与思路分析</description><pubDate>Fri, 02 Jan 2026 22:49:00 GMT</pubDate><content:encoded>&lt;p&gt;import ProblemCard from &apos;../../components/ProblemCard.astro&apos;;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/contest/1506/problem/D&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;D Epic Transformation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目描述&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个数组a, $a_1,a_2...a_n$&lt;/p&gt;
&lt;p&gt;每次选择两个不同的$a_i,a_j$删除， 求最后的数个数最小多少&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;思路分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;找到最多的数(有x个), 如果$x &amp;gt; \frac{n+1}{2}$ ,答案就是$x - (n - x) == 2x-n$&lt;/p&gt;
&lt;p&gt;否则n是奇数答案为1， n是偶数答案为0&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;void solve() {
    int n; cin &amp;gt;&amp;gt; n;
    int z = 0;
    map&amp;lt;int,int&amp;gt; m;
    for (int i = 1; i &amp;lt;= n; ++i) {
        int x; cin &amp;gt;&amp;gt; x;
        m[x]++;
        z = max(z, m[x]);
    }
    if (2 * z &amp;gt; n) cout &amp;lt;&amp;lt; (2 * z - n) &amp;lt;&amp;lt; &quot;\n&quot;;
    else cout &amp;lt;&amp;lt; (n % 2) &amp;lt;&amp;lt; &quot;\n&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/contest/1520/problem/E&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;E Arranging The Sheep&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目描述&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个字符串&lt;code&gt;**.**..**&lt;/code&gt;之类的， 每次可以让&lt;code&gt;*&lt;/code&gt;向右边或者左边移动一格(如果左边或者右边是&lt;code&gt;.&lt;/code&gt;)， 求移动次数最少可以让&lt;code&gt;*&lt;/code&gt;全部挨在一起&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;思路分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;先假设第i个&lt;code&gt;*&lt;/code&gt;是标准， 那么1 ~ i-1的&lt;code&gt;*&lt;/code&gt;j要向右走x - (i - j)&lt;/p&gt;
&lt;p&gt;如果我们枚举每头🐏然后再计算每头🐏的举例就是$O(n^2)$直接TLE&lt;/p&gt;
&lt;p&gt;根据数学中位数， 可以知道数列中到中间的数的距离和是最短的&lt;/p&gt;
&lt;p&gt;举个例子: 1 4 5 7 10&lt;/p&gt;
&lt;p&gt;1 : 3 + 4 + 6 + 9 = 22&lt;/p&gt;
&lt;p&gt;4 : 3 + 1 + 3 + 6 = 13&lt;/p&gt;
&lt;p&gt;5 : 4 + 1 + 2 + 5 = 12&lt;/p&gt;
&lt;p&gt;7 : 6 + 3 + 2 + 3 = 14&lt;/p&gt;
&lt;p&gt;10: 9 + 6 + 5 + 3 = 23&lt;/p&gt;
&lt;p&gt;怎么证明? 当x小于中间数时, 他向右移动, 右边的数$t* (n - x)$少走加入t步, 左边的数就多走$t*(x-1)$步, 总和就会变小, 同理当x大于中间数&lt;/p&gt;
&lt;p&gt;向左走的时候总和变小&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;void solve() {
    int n; cin &amp;gt;&amp;gt; n;
    int cnt = 0;
    for (int i = 1; i &amp;lt;= n; ++i) {
        char c;
        cin &amp;gt;&amp;gt; c; 
        if (c == &apos;*&apos;) {
            a[++cnt] = i;
        }
    }
    if (cnt == 0) {cout &amp;lt;&amp;lt; &quot;0\n&quot;; return;}
    ll ans = 0;
    int mid = (cnt + 1) / 2;
    for (int i = 1; i &amp;lt;= cnt; ++i) {
        ans += abs(a[i] - a[mid] - (i - mid));
    }
    cout &amp;lt;&amp;lt; ans &amp;lt;&amp;lt; &quot;\n&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/contest/1605/problem/C&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;C Dominant Charcter&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目描述&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;有一个字符串s, 仅仅由abc三个字符（都是可有可无的）组成, 求s的字串中满足$cnt_a &amp;gt; cnt_b &amp;amp; cnt_a &amp;gt; cnt_c$ 的个数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;思路分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;找到一个最小元字串满足题意, 其他任意字串可以由元字串来拼凑&lt;/p&gt;
&lt;p&gt;1 ： a    1+0+0&lt;/p&gt;
&lt;p&gt;2 :   aa  2+0+0&lt;/p&gt;
&lt;p&gt;3 :  aaa aba aca 2+1+0&lt;/p&gt;
&lt;p&gt;4:   abca acba 2+1+1&lt;/p&gt;
&lt;p&gt;5:   ababa acaca 3+2+0&lt;/p&gt;
&lt;p&gt;6:   abbaca accaba 3+2+1&lt;/p&gt;
&lt;p&gt;7:   abbacca 3+2+2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;void solve() {
    int n; cin &amp;gt;&amp;gt; n;
    string s; cin &amp;gt;&amp;gt; s;
    int ans = 1e9;
    for (uint i = 0; i &amp;lt; s.size(); ++i) {
        int cnt[3] = {0};
        for (int k = 0; k &amp;lt; 7; ++k){
            if (i + k &amp;gt;= s.size()) break;
            cnt[s[i+k]-&apos;a&apos;]++;
            if (k &amp;gt;= 1 &amp;amp;&amp;amp; cnt[0] &amp;gt; cnt[1] &amp;amp;&amp;amp; cnt[0] &amp;gt; cnt[2]) {
                ans = min(ans, k+1);
                break;
            }
        }
    }
    cout &amp;lt;&amp;lt; (ans == 1e9 ? -1 : ans) &amp;lt;&amp;lt; &quot;\n&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/contest/1526/problem/B&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;B I hate 1111&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;一个整数n能否被11, 111, 1111, 11111....相加得到?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;思路分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;发现1111 = 11 + 111 * 10&lt;/p&gt;
&lt;p&gt;11111 = 1111 * 10 + 11&lt;/p&gt;
&lt;p&gt;所以元整数是11和111&lt;/p&gt;
&lt;p&gt;$n=11x+111y$&lt;/p&gt;
&lt;p&gt;因为11个111可以换成111个11， 所以我们只需要列举0~10个111看看是否有解&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;void solve() {
    int n; cin &amp;gt;&amp;gt; n;
    for (int i = 0; i &amp;lt;= 10; ++i) {
        if (n - i * 111 &amp;gt;= 0 &amp;amp;&amp;amp; (n - i * 111) % 11 == 0){
            cout &amp;lt;&amp;lt; &quot;YES\n&quot;;
            return;
        }
    }
    cout &amp;lt;&amp;lt; &quot;NO\n&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/problemset/problem/1551/B2&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;B2 Wonderful Coloring - 2&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;有一个数组$a_1,a_2,a_3....a_n$, 有$k$种颜色&lt;/p&gt;
&lt;p&gt;要求:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一个颜色涂的格子不能有相同值&lt;/li&gt;
&lt;li&gt;让所有涂色的格子的总值尽可能高&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;思路分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;解法一: 一个链式前向星存储每种值+ 他们的位置,  然后我们从最大值开始涂色，限制同一个值不能涂色超过k次, 桶排序&lt;/p&gt;
&lt;p&gt;解法二: 用vector存储每种值加位置， 然后也是从最大值涂色.....&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;const int MAXN = 2e5 + 1;
int head[MAXN], pos[MAXN], nxt[MAXN], tot;
int c[MAXN];
int n, k;
void init() {
    for (int i = 1; i &amp;lt;= n; ++i) {head[i] = -1; c[i] = 0;}
    tot = 0;
}
void insert(int val, int p) {
    ++tot;
    pos[tot] = p;
    nxt[tot] = head[val];
    head[val] = tot;
}
void solve() {
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; k;
    init();
    int mx_val = 0;
    for (int i = 1; i &amp;lt;= n; ++i) {
        int v; cin &amp;gt;&amp;gt; v;
        insert(v, i);
        mx_val = max(v, mx_val);
    }
    vector&amp;lt;int&amp;gt; paint;
    for (int i = mx_val; i &amp;gt;= 1; --i) {
        if (head[i] == -1) continue;
        int count = 0;
        for (int j = head[i]; j != -1; j = nxt[j]) {
            if (count &amp;lt; k) {
                paint.push_back(pos[j]);
                count++;
            }
        }
    }
    int painted = paint.size() / k * k;
    for (int i = 0; i &amp;lt; painted; ++i) c[paint[i]] = i % k + 1;
    for (int i = 1; i &amp;lt;= n; ++i) cout &amp;lt;&amp;lt; c[i] &amp;lt;&amp;lt; &quot; &quot;;
    cout &amp;lt;&amp;lt; &quot;\n&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/problemset/problem/1624/D&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/problemset/problem/1551/B2&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/problemset/problem/1515/C&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/problemset/problem/1463/B&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/problemset/problem/1535/C&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1400}
link=&quot;https://codeforces.com/problemset/problem/1475/C&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Codeforces</category><author>Qingw</author></item><item><title>Goodbye2025</title><link>https://qingw.top/posts/Goodbye2025/</link><guid isPermaLink="true">https://qingw.top/posts/Goodbye2025/</guid><description>Goodbye2025 题解与思路分析</description><pubDate>Fri, 02 Jan 2026 18:14:00 GMT</pubDate><content:encoded>&lt;p&gt;import ProblemCard from &apos;../../components/ProblemCard.astro&apos;;&lt;/p&gt;
&lt;h1&gt;Goodbye2025&lt;/h1&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1200}
link=&quot;https://codeforces.com/contest/2178/problem/C&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;C. First or Second&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目描述&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个数组a, 每次从a的第一个或者第二个选择一个数$a_i$, 如果是第一个数则$X + a_i$否则$X - a_i$&lt;/p&gt;
&lt;p&gt;求X的最大值(当a只剩下一个数的时候停止)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;思路分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;反向思考 ： 来列举剩下的$a_i$&lt;/p&gt;
&lt;p&gt;我们可以发现 : $a_i$的右边一定是被$-a_i$的(可以用suf后缀和优化)， 左边可能是$+a_i$也可能是$-a_i$(除了第一个肯定是+)&lt;/p&gt;
&lt;p&gt;我们需要列举每个剩下的$a_i$然后求最大值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;void solve() {
	int n; cin &amp;gt;&amp;gt; n;
    for (int i = 1; i &amp;lt;= n; ++i) cin &amp;gt;&amp;gt; a[i];
    suf[n + 1] = 0;
    for (int i = n; i &amp;gt;= 1; --i) {
		suf[i] = suf[i+1] - a[i];
    }
    ll ans = -1e9, pre = 0;
    for (int i = 1; i &amp;lt;= n; ++i) {
		ans = max(ans, pre + suf[i + 1]);
       	if (i == 1) pre += a[i];
        else pre += abs(a[i]);
    }
    cout &amp;lt;&amp;lt; ans &amp;lt;&amp;lt; &quot;\n&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ProblemCard
platform=&quot;Codeforces&quot;
rating={1200}
link=&quot;https://codeforces.com/contest/2178/problem/D&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;D. Xmas or Hysteria&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;题目描述&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;有n个精灵， 他们有$a_i$的生命和攻击力, 我们需要在X个回合后仍然需要m个精灵存活, 是否存在一个迭代序列满足条件? (迭代: 当所有存活的精灵都主动攻击后才会停止， 一个迭代指的是A攻击B， $h_a\to{h_a-a_b} h_b\to{h_b-a_a}$)， 每个精灵的$a_i$都不同(distinct)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;思路分析&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;因为一次攻击至少死一个精灵， 所以迭代最多是$\lfloor{\frac{n}{2}}\rfloor$, 存活的精灵最多是$\lfloor{\frac{n}{2}}\rfloor$&lt;/p&gt;
&lt;p&gt;把精灵按照攻击力从低到高排序&lt;/p&gt;
&lt;p&gt;分类讨论m :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;m &amp;gt; $\lfloor{\frac{n}{2}}\rfloor$  不合法&lt;/li&gt;
&lt;li&gt;m = 0 : 所有人攻击最大的看看有没有可能干死他， 如果可以， 我们看看是第i个干死他， 然后剩下的精灵就按照链式送死个第i个， 然后i再取干最大的&lt;/li&gt;
&lt;li&gt;m &amp;gt; 0 : 我们让 1 ~ n - 2(m-1)的精灵只剩下一个, n - 2(m-1)+1 ~ n的精灵剩下m-1, 这样就有m个了&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;array&amp;lt;int, 2&amp;gt; a[MAXN];
void solve() {
	int n, m; cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;
    if (m &amp;gt; n / 2) {
        cout &amp;lt;&amp;lt; &quot;-1\n&quot;;
        return;
    }
    for (int i = 1; i &amp;lt;= n; ++i) cin &amp;gt;&amp;gt; a[i][0], a[i][1] = i;
    sort(a + 1, a + 1 + n);
    vector&amp;lt;array&amp;lt;int, 2&amp;gt;&amp;gt; ans;
    if (m == 0) {
        ll total = 0;
        for (int i = 1; i &amp;lt;= n - 1; ++i) total += a[i][0];
        if (total &amp;lt; a[n][0]) {
            cout &amp;lt;&amp;lt; &quot;-1\n&quot;;
            return;
        }
        for (int i = n-1; i &amp;gt;= 1; --i) {
			a[n][0] -= a[i][0];
            if (a[n][0] &amp;lt;= 0) {
                for (int j = 1; j &amp;lt; i; ++j) {
                    ans.push_back({a[j][1], a[j+1][1]});
                }
                ans.push_back({a[i][1], a[n][1]});
                break;
            }
            ans.push_back({a[i][1], a[n][1]});
        }
        
    }else {
        for (int i = 1; i &amp;lt;= n - 2*(m - 1)-1; ++i) { // 贡献一个精灵
            ans.push_back({a[i+1][1], a[i][1]});
        }
        for (int i = n - 2*(m-1) + 1; i &amp;lt;= n-1; i += 2) { // 贡献m-1个精灵
			ans.push_back({a[i+1][1], a[i][1]});
        }
    }
    cout &amp;lt;&amp;lt; ans.size() &amp;lt;&amp;lt; &quot;\n&quot;;
    for (auto [x, y] : ans) cout &amp;lt;&amp;lt; x &amp;lt;&amp;lt; &quot; &quot; &amp;lt;&amp;lt; y &amp;lt;&amp;lt; &quot;\n&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><category>Codeforces</category><author>Qingw</author></item></channel></rss>