100洛谷蓝/紫题计划--start from 0526
让我们开始吧
No.1 P1777 帮助 ------(紫) 2025.5.27
首先阅读题面,发现一个关键信息——每本书的编号均在 \(25\) 到 \(32\) 间—— 一共 \(8\) 种
状态压缩 \(dp\) 就行了
我们考虑设f[i][j][k][s] 表示当前我们考虑到第 \(i\) 个数,一共有 \(j\) 个被重新排列,所有被重排的数字集合是 \(k\) ,最后一个没有被挑出来的数是 \(s\) 的最小代价
转移方程自己想吧
注意空间限制,不用滚动数组什么优化的话就得开小一点,用 \(int\) 就行了
CODE
No.2 P4928 [MtOI2018] 衣服?身外之物!------(蓝) 2025.5.27
相对于上一道题来说,蓝题还是稍微简单一点的
首先,衣服一共不超过四种,这启示我们写状压 \(dp\)
但是要注意的是,我们应该用 \(7\) 进制而非 \(2\) 进制,因为每件衣服有 \(7\) 个数字用来表示其状态
然后就做完了
CODE
No.3 P3873 [TJOI2010] 天气预报 ------ (蓝) 2025.5.28
一眼矩阵快速幂板子
不会矩阵快速幂怎么办呢?
搜板子呗......
然后?没有然后了,就是个板子,回去重学矩阵快速幂吧
CODE
No.4 P5357 【模板】AC 自动机------(蓝) 2025.6.26
(又是不写题的一个月)
AC自动机版子,后面还有两个简单版
CODE
No.5 P3808 AC 自动机(简单版)------(蓝) 2025.6.26
(略)
CODE
No.6 P3796 AC 自动机(简单版 II)------(蓝) 2025.6.26
(略)
CODE
No.7 P5787 二分图 /【模板】线段树分治------(蓝) 2025.6.28
首先,二分图可以用并查集来搞
其次,我们考虑用线段树分治
具体呢?
对于每一条边,它都有一个影响时间 \(l+1-->r\) ,以及一个修改
这就很像线段树的区间修改了
然后?没有然后了
CODE
No.8 P5214 [SHOI2014] 神奇化合物------(蓝) 2025.6.28
又是一道线段树分治
很板
我们考虑在 \(merge\) 时将当前联通块数量减一,同样的,在回溯时将其加回来就行了
注意我们读入边的方式多样,针对自己的做法,要注意读入边 \(a,b\) 要保证 \(a<b\) ,具体请看代码
CODE
No.9 P2106 Sam 数------(蓝) 2025.6.29
简短的题面......
注意到数据范围 \(n \leq 10^{18}\) ,所以我们需要一个 \(log_2 n\) 级别的算法,是什么呢???
矩阵快速幂
我们设上一层的矩阵为
依次表示以 \(0,1,2,3,....\) 结尾的,长度为 \(i-1\) 的 \(Sam\) 数有多少个
同理,设此层的为
则易得转移方程为
然后我们可以写出转移矩阵 \(x\) 应该长下面这样
然后就是矩阵快速幂版子了
注意:赋值矩阵时一定不要少赋值几行
CODE
No.10 P4124 [CQOI2016] 手机号码------(蓝) 2025.6.29
数位dp
详情见题解(其实不是自己写的)
\(dp\) 写不出来的话,多想想记忆化搜索,会好写很多
CODE
No.11 P4159 [SCOI2009] 迷路------(蓝) 2025.6.30
矩阵快速幂
题目中给出了一个邻接矩阵,求从点 \(1\) 到 \(n\) 的长度为 \(t\) 的路径数,对 \(2009\) 取模
我们先考虑一下如果所有数字均为 \(0/1\) 时如何解决
显然,当前的矩阵可以视为第 \(1\) 层的矩阵, \(matrix_{1,i,j}\) 就可以表示从点 \(i\) 到点 \(j\) 路径长度为 \(1\) 的方案数(这里的 \(1\) 表示路径长度)
那么,我们就有一个转移
(与 \(Floyd\) 传递闭包极其相似)
这不就是矩阵快速幂板子吗
对于 \(t\) 路径长度,我们需要将 \(t\) 个邻接矩阵相乘即为答案
回到最开始的问题,这是对于 \(0/1\) 矩阵的做法,我们如何推广呢?
考虑到 \(n\) 的取值范围较小 \((1-10)\) 我们可以暴力拆点,把每一个点拆成 \(9\) 个,然后建立长度为 \(1\) 的边。这样,我们的矩阵就是 \(0/1\) 矩阵了。
要注意的是,矩阵快速幂一定要用 单位矩阵 做基础,不能直接乘 \(QAQ\)
CODE
No.12 P5004 专心OI - 跳房子------(蓝) 2025.6.30
没错,又又又又是矩阵快速幂(\(doge\))
但是要注意是至少隔了 \(m\) 个格子,也就是说,从 \(i\) 号格子至少要跳到 \(i+m+1\) 格子之后
设 \(f(n)\) 为正好跳到 \(n\) 号格子的方案数
我们手玩一下 \(m \leq 5\) 的情况,可以发现一个规律:
为啥呢?
手玩的(bushi)
其实我们可以这样解释:
对于位置 \(x\) 而言,它可以从满足 \(0 \leq i\leq x-m-1\) 的任意一个位置转移过来
而对于 \(x-1\) 而言,它可以从 \(0\leq i\leq x-m-2\) 的任意一个位置转移,这是被完全包含在 \(x\) 位置中的
那么,\(f(x)\) 就可以拆成两部分了
然后就开始构造矩阵吧
没啥可说的,大概长下面这样:(以 \(m=4\) 为例)
接下来我们做一个该矩阵的 \(n\) 次幂即可,
最后我们输出 \(ans.matrix_{1,m}\)
因为我们只统计路径不同的数量而不关心结尾到底在哪个位置,所以不需要做和,而 \(ans.matrix_{1,m}\) 包含了结尾为 \(1\leq k\leq n\) 所有情况,所以它就是正确答案
注意这里需要把 \(m\) 加一,具体细节请见代码
CODE
No.13 P5337 [TJOI2019] 甲苯先生的字符串 ------(蓝) 2025.6.30
矩阵乘法水题,不多说了,一发过
算了还是说一说吧
考虑直接构造一个 \(26\times 26\) 矩阵来表示我们可以在构造的字符串中从 \(ch1\) 到 \(ch2\) 的方案数,如果没有在 \(s\) 中出现过,则说明可以相邻,赋值为 \(1\),否则为 \(0\)
然后就做完了
CODE
No.14 P10502 Matrix Power Series ------(蓝) 2025.6.30
也是经典矩阵乘法
题目中给出了一个矩阵 \(A\) ,要求求出 \(A\) 的 \(1\) 到 \(k\) 次幂之和 \((1\leq k\leq 10^{9})\)
暴力做法显然是 $O(n^{2} k) $ 的,过不了,我们考虑加速计算过程
对于任意一个 \(k\) ,我们可以采取分治的做法,每次劈成两半进行计算,具体过程如下(假设其为函数 \(f(k)\))
于是我们递归计算即可
我们每进行一次快速幂为 \(O(n^{2} log_2 k)\) 的复杂度,在整个运算中,我们递归了 \(log_2 k\) 层,每层最多运用了两次快速幂,所以整个时间复杂度为 \(O(n^{2} log_2^{2} k)\) ,可以过掉本题
注意:对矩阵进行初始化操作时要注意范围,最好用多少赋值多少,多赋值容易 \(TLE\)
CODE
No.15 P1972 [SDOI2009] HH的项链 ------(蓝) 2025.6.30
多年之前的题目了
这道题我们不能直接利用权值树状数组来保存,因为当我们给出 \(l\),\(r\)时,我们不能快速确定区间内的数字个数
关于 \(r\) ,是好做的,我们可以把所有询问按照右端点排个序
但是,我们没办法处理 \(l\)
我们考虑放弃常规的权值树状数组,对于每种数字 \(i\) ,我们可以保存一个 \(vis_{i}\) 表示最后出现的位置,每次新加入数字时,把前面相同数字的贡献删掉再加入新的贡献
为啥对呢?因为对于每种数字,我们其实只关心最后一个在\(r\)之前出现的位置
这样,我们不用权值树状数组也就能够快速统计数字的种类数,同时能够保证对每一个 \(l,r\) 都能够统计了
CODE
No.16 P1306 斐波那契公约数 ------(蓝) 2025.6.30
这就是今天最后一道了
还是矩阵快速幂,我们需要求出斐波那契数列中的第 \(n,m\) 项的 \(gcd \bmod (10^{9}+7)\) 的值
结论:\(\gcd(F_n,F_m) = F_{\gcd(n,m)}\)
证明:
我们设 \(n < m ,F_n=a,F_{n+1}=b\)
则有 \(F_{n+2}=a+b,F_{n+3}=a+2b,F_{n+4}=2a+3b,......\)
可得 \(F_{m}=F_{m-n-1} \times a+F_{m-n} \times b\)
则可得 \(\gcd(F_n,F_m)=\gcd(a,F_{m-n-1} \times a+F_{m-n} \times b)=\gcd(F_n,F_{m-n}\times F_{n+1})\)
这里引理:\(gcd(F_n,F_{n+1})=1\),证明如下
由欧几里得定理可得:
即 \(\gcd(F_n,F_{n+1}) =1\),证毕
由引理可知 \(F_n\),\(F_{n+1}\) 互质
那么 \(\gcd(F_n,F_m)=\gcd(F_n,F_{m-n})\)
接下来我们递归处理即可得到 \(\gcd(F_n,F_m) = F_{\gcd(n,m)}\)
然后就做完了
CODE
No.17 P1345 [USACO5.4] 奶牛的电信Telecowmunication ------(蓝) 2025.7.1
省流:网络流最小割
网络流是坐实了,但是最小割是求边的,而不是点,咋办呢?
拆点!
我们可以把每一个点 \(nd\) 拆成 \(nd1\) 和 \(nd2\) 两个点,一个连 \(nd\) 的出边,一个连入边(无向边可以分为一条出边,一条入边),并且连接一条从 \(nd1\) 指向 \(nd2\) 的边,其边权为 \(1\) (毕竟每一个点只有 \(1\) 的流量 )
然后我们将所有其他边均赋值一个 \(inf\) 边权,跑最小割即可
CODE
No.18 P1360 [USACO07MAR] Gold Balanced Lineup G ------(蓝) 2025.7.2
既然是求一段连续区间使提升能力值相同,那么这段区间的起点和终点的前缀和数组 \(num\) 各个数字之间的相对大小应该一样
也就是说,对于这段区间的起点和终点有 \(\forall i \in [0,m) \bigcup \mathbb{Z} , num_i-num_0\) 不变
找出不变量之后,我们就可以考虑利用 map<vector<ll>,ll> 以当前状态为下标,存储第一次出现位置,然后作差求最大值即可
CODE
No.19 P9356 「SiR-1」Bracket ------(紫) 2025.7.2
不会,详情见题解(思路理解,不会码)
CODE
No.20 P4145 上帝造题的七分钟 2 / 花神游历各国 ------(蓝) 2025.7.3
我们考虑每次开方操作直接对所有叶子节点暴力修改,记录一下当前区间内是否还有能够开方的数 \(x\) (即 $\exist x> 1 $),如果没有就不做修改,否则暴力修改即可
为什么这个复杂度是正确的呢?
我们考虑在本题中对于每个数 \(x\) ,都有 \(x \leq 10^{12}\) ,再加上的向下取整也就是说,每个数开方不超过 \(7\) 次就会变成 \(1\) ,就算对所有数都做一遍,也最多是 \(nlogn\times 7\) 的,不超过时限,因此可做
CODE
No.21 P3377 【模板】左偏树/可并堆 ------(蓝) 2025.7.3
一道板子题
可并堆,顾名思义,就是能够合并的堆,其实就是一个树状结构
这里以小根堆为例
对于一个小根堆,每一个节点的 \(val\) 都小于其子树中所有子节点的 \(val\),同时,我们如果用左偏树来维护的话,就要求我们所建的树满足 \(dist_{ls} \le dist_{rs}\)
我们来看一下 \(dist\) 的递推式:
dist[i]=min(dist[ls[i]],dist[rs[i]])+1;
大概就是这样,维护 \(dist\) 数组可以有效保证我们代码的运行效率为 \(log\) ,具体证明看这里
这里放一下代码,不做赘述,如有不理解请参照其他题解(毕竟就是个板子,没啥好解释的)
CODE
No.22 P2824 [HEOI2016/TJOI2016] 排序 ------(紫) 2025.7.3
本系列第 \(3\) 道紫题 \(QAQ\)
其实是线段树板子加上 \(0/1\) 经典套路
显然,这道题的答案就在原数组中,我们考虑用二分答案解决此题,关键在于 \(check()\) 函数如何写
有一个代代相传的套路就是将大于等于 \(mid\) 的数赋值为 \(1\) ,否则赋值为 \(0\) ,此时,我们的区间排序操作就可以转化为区间赋值操作(只有两种数字),我们可以利用线段树统计当前区间内 \(1,0\) 的个数然后进行赋值,这样做是 \(O(logn)\) 的,最后返回 \(q\) 位置上的数 \((0/1)\) 即可
整个算法的复杂度是 \(O(m\times log^{2} (n))\) 的,可以通过,代码见下
CODE
No.23 P4198 楼房重建 ------(紫) 2025.7.3
单边递归线段树板子,不作解释,请见题解
CODE
No.24 P4396 [AHOI2013] 作业 ------(紫) 2025.7.4
显然是我们的莫队啊
既然是维护在一段区间以内的 \([a,b]\) 之间的数值种类和出现个数,我们不难想到可以用莫队套权值线段树来做,时间复杂度为 \(O(n \sqrt n \times log_2n)\)的
但是,莫队本身就跑的慢,再加上线段树的大常数特性和临近时限的复杂度, \(TLE\) 自然是不用说的事
那么就用树状数组吧!
开两个树状数组分别来表示数值的个数和数字总数,对于数字总数,我们直接维护即可,而对于数值种类,我们再开一个 \(cnt\) 数组统计个数,在 \(cnt_i\) 从 \(0\) 变为 \(1\) 或是从\(1\) 变为 \(0\) 时进行单点修改即可
注意时限紧,要卡常
CODE
No.25 P2865 [USACO06NOV] Roadblocks G ------(蓝) 2025.7.7
次短路模板,不作赘述
CODE
No.26 P7297 [USACO21JAN] Telephone G ------(蓝) 2025.7.7
比较水的一道蓝题
有一个非常直观的想法就是我们对于 \(i\) 号点,只连接每种能和它连接的品种中,离他最近的两个节点
大概就是这样,其中 \(i\) 号点能和所有蓝色点,红色点连接,不同颜色代表不同品种

为啥这样对呢?
我们考虑向后跳的话,因为是跳到 \(n\) 号点,无可避免,所以不劣,这一部分是不管如何跳都要走的。
其次我们考虑向前跳,跳到离他最近的节点可以尽量缩小我们返回时的距离,而且如果下一步还要往前的话,他也和其他方案代价相同,不劣。
那么到这里我们就做完了,注意要特别连接 \(1\) 号点和 \(n\) 号点,不然会错
CODE
No.27 P1772 [ZJOI2006] 物流运输 ------(蓝) 2025.7.7
说实话,这题有点诈骗
看到这东西我居然第一想法是跑分层图,我只能说没救了,后来看到要求每次更改路径都要加上一个代价 \(k\) 才反应过来这不是分层图
显然,我们直接跑是不好统计的,但我们注意到 \(n\le 100\) ,也就意味着我们可以枚举采用同一条路径的连续区间
考虑设 \(f_{i}\) 表示我们当前做到了第 \(i\) 天的最小代价,那么转移式子显然为:
其中 \(w_{j,i}\) 表示第 \(j\) 天到第 \(i\) 天的最小代价,由于 \(m\le 20\) 的范围极小,所以我们直接利用 \(Floyd\) \(n^3\) 跑最短路即可,每次枚举 \(i,j\) 将邻接矩阵按照每个点的状态 (是否能够经过)进行重新赋值,然后跑最短路即可,复杂度 \(O(n^2 \times m^3)\) ,可以通过。
CODE
No.28 P5631 最小mex生成树 ------(紫) 2025.7.7
这道题显然可以用线段树分治来做
我们考虑一个数 \(x\) 成为答案的必要条件,就是它必须要满足去掉所有边权为 \(x\) 的边后,整个图仍然联通
那么我们考虑维护一个可撤销并查集,搭配上线段树分治,实时维护图的联通块数,当我们走到叶子节点时,若是整图只有一个连通块,就可以输出答案了
怎么维护连通块数呢?做过原题,具体请见本集合No.8 P5214 [SHOI2014] 神奇化合物
其他细节请见代码
CODE
No.29 P6378 [PA 2010] Riddle ------(蓝) 2025.7.8
优化建图板子,不做解释
CODE
No.30 P4819 [中山市选] 杀人游戏 ------(紫) 2025.7.8
这道题是 \(Tarjan\) 板子
我们考虑对于任何一个强连通分量,我们只需要去查验其中一个人的身份即可,其他人的身份我们便可以无伤查询
那我们就先缩点,转换为一个 \(DAG\) 上的问题了
我们可以很显然的得到一个结论:我们需要查询的点数为入度为 \(0\) 的点数 (可能-1)
(至于为啥,自己想去,推一推,画一画就出来了)
结束了
CODE
No.31 P3530 [POI 2012] FES-Festival ------(蓝) 2025.7.8
看题解去吧
CODE
No.32 P11360 [CEOI 2015] 管道 ------(紫) 2025.7.8
我们考虑对于一条割边,它一定会出现在这个图的生成树上,那么我们随便生成一棵生成树,对于所有边,我们都随机一个数值 \(rand\) ,给它的一个端点加上 \(rand\) ,另一个减去
此时我们遍历这一整棵树,对于每一个节点求一个子树和 \(sum\) ,若 \(sum = 0\) ,则说明这是一条桥,我们输出即可
至于为什么,请见题解第一篇
CODE
No.33 P4460 [CQOI2018] 解锁屏幕 ------(蓝) 2025.7.9
赛时切的水题,懒得喷

半途而废的计划
浙公网安备 33010602011771号