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\) 级别的算法,是什么呢???

矩阵快速幂

我们设上一层的矩阵为

\[ a_{i-1,0} , a_{i-1,1} , a_{i-1,2} , a_{i-1,3} , a_{i-1,4} , a_{i-1,5} , a_{i-1,6} , a_{i-1,7} , a_{i-1,8} , a_{i-1,9} \]

依次表示以 \(0,1,2,3,....\) 结尾的,长度为 \(i-1\) 的 \(Sam\) 数有多少个

同理,设此层的为

\[ a_{i,0} , a_{i,1} , a_{i,2} , a_{i,3} , a_{i,4} , a_{i,5} , a_{i,6} , a_{i,7} , a_{i,8} , a_{i,9} \]

则易得转移方程为

\[ a_{i,0}=a_{i-1,0}+a_{i-1,1}+a_{i-1,2}\\ a_{i,1}=a_{i-1,0}+a_{i-1,1}+a_{i-1,2}+a_{i-1,3}\\ a_{i,2}=a_{i-1,0}+a_{i-1,1}+a_{i-1,2}+a_{i-1,3}+a_{i-1,4}\\ a_{i,2}=a_{i-1,1}+a_{i-1,2}+a_{i-1,3}+a_{i-1,4}+a_{i-1,5}\\ ......\\ a_{i,9}=a_{i-1,7}+a_{i-1,8}+a_{i-1,9} \]

然后我们可以写出转移矩阵 \(x\) 应该长下面这样

\[x= \begin{Bmatrix} 1&1&1&0&0&0&0&0&0&0\\ 1&1&1&1&0&0&0&0&0&0\\ 1&1&1&1&1&0&0&0&0&0\\ 0&1&1&1&1&1&0&0&0&0\\ 0&0&1&1&1&1&1&0&0&0\\ 0&0&0&1&1&1&1&1&0&0\\ 0&0&0&0&1&1&1&1&1&0\\ 0&0&0&0&0&1&1&1&1&1\\ 0&0&0&0&0&0&1&1&1&1\\ 0&0&0&0&0&0&0&1&1&1 \end{Bmatrix} \]

然后就是矩阵快速幂版子了

注意:赋值矩阵时一定不要少赋值几行

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\) 表示路径长度)

那么,我们就有一个转移

\[matrix_{num,i,j}=\sum_{k = 1}^n (matrix_{num-1,i,k} \times matrix_{1,k,j}) \]

(与 \(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\) 的情况,可以发现一个规律:

\[\textstyle f(x)= \begin{cases} 1 & 0 \leq x \leq m \\ f(x-1) + f(x-m-1) & m\leq x \end{cases} \]

为啥呢?

手玩的(bushi)

其实我们可以这样解释:

对于位置 \(x\) 而言,它可以从满足 \(0 \leq i\leq x-m-1\) 的任意一个位置转移过来

而对于 \(x-1\) 而言,它可以从 \(0\leq i\leq x-m-2\) 的任意一个位置转移,这是被完全包含在 \(x\) 位置中的

那么,\(f(x)\) 就可以拆成两部分了

然后就开始构造矩阵吧

没啥可说的,大概长下面这样:(以 \(m=4\) 为例)

\[x= \begin{Bmatrix} 0 &0& 0& 0& 1\\ 1 &0& 0& 0& 0\\ 0 &1& 0& 0& 0\\ 0 &0& 1& 0& 0\\ 0 &0& 0& 1& 1 \end{Bmatrix} \]

接下来我们做一个该矩阵的 \(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)\))

\[\textstyle f(k)= \begin{cases} A^{k} + f(\lfloor \frac k{2}\rfloor) \times A^{\lfloor \frac k{2}\rfloor} & k\bmod 2 =1 \\ f(\frac k{2}) \times A^{\frac k{2}} & k\bmod 2 =0\end{cases} \]

于是我们递归计算即可

我们每进行一次快速幂为 \(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\),证明如下

由欧几里得定理可得:

\[\begin{aligned} \gcd(F_n,F_{n+1}) &=\gcd(F_n,F_{n+1}-F{n}) \\ &=gcd(F_{n-1},F_{n}) \\&=\gcd(F_{n-2},F_{n-1})\\& ......\\&=\gcd(F_1,F_2)=1 \end{aligned} \]

即 \(\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\) 号点能和所有蓝色点,红色点连接,不同颜色代表不同品种
1

为啥这样对呢?

我们考虑向后跳的话,因为是跳到 \(n\) 号点,无可避免,所以不劣,这一部分是不管如何跳都要走的。

其次我们考虑向前跳,跳到离他最近的节点可以尽量缩小我们返回时的距离,而且如果下一步还要往前的话,他也和其他方案代价相同,不劣。

那么到这里我们就做完了,注意要特别连接 \(1\) 号点和 \(n\) 号点,不然会错

CODE

No.27 P1772 [ZJOI2006] 物流运输 ------(蓝) 2025.7.7

说实话,这题有点诈骗

看到这东西我居然第一想法是跑分层图,我只能说没救了,后来看到要求每次更改路径都要加上一个代价 \(k\) 才反应过来这不是分层图

显然,我们直接跑是不好统计的,但我们注意到 \(n\le 100\) ,也就意味着我们可以枚举采用同一条路径的连续区间

考虑设 \(f_{i}\) 表示我们当前做到了第 \(i\) 天的最小代价,那么转移式子显然为:

\[f_i = \min_{1 \le j \le i} (w_{j,i}+f_j+k) \]

其中 \(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

赛时切的水题,懒得喷

CODE

就到这里吧,后面可能还会更新,但是仅限于自己切的题

posted @ 2025-10-17 15:49  Floyd_Hyacinth  阅读(132)  评论(0)    收藏  举报