2026 1月 训练记录
前情提要
新的一年开始了,看着日历上的年份还感到陌生,训练仍是需要被记录的。
1.1
下午把昨天下午那题过了。一道普通多维线性 DP+前缀和优化,只是昨天状态定义复杂了,不好转移。其实我的做法也还可以把第一维从 30 降到 10(三种括号分别存储,不必计统计总数),导致常数是别人的三倍,但是不管了,还是可以过。
晚上想写下 https://www.luogu.com.cn/problem/UVA1630 。很快就过了,一道很简单的区间 DP,估计真实难度为绿(提交的工单过了)。我直接写的
1.2
早上起来水了 P5752,把式子化简一下,发现答案只与平方和有关,然后用二维区间 DP(也就是在矩形上 DP)直接解决即可。
晚上想做一下 https://www.luogu.com.cn/problem/UVA10559 。结果想了一会儿发现不会,只会
1.3
假期结束了,晚上回校打了 abc,开 urt 打了 EF(while 写成 if 调了一个小时)。
1.4
下午写过了 UVA10559。怎么直接
把 UVA1292 写了,买啥好说的。又把 UVA1222 写了,还是没啥好说的,树形背包 DP 板题,难点甚至在于输入时的字符串处理。又把 P10962 写过了,还是没啥好说的,换根 DP 板子。
晚上切了 P3211,分每一位考虑,倒序计算期望,然后列出转移方程,再转到矩阵中,然后跑一遍高斯消元,时间复杂度
1.5
早上把 P10963 做了,直接根据题意状压,虽然理论时间复杂度
上午想写下 P7689,结果想了一节课只会超高复杂度做法,不用细想都知道不可行,决定查阅题解。改过来了,还是最优解。这道题的关键在于,我们发现如果只用 0/1 来记录状态的话会非常麻烦,需要记录两行,这样转移时就需枚举三行,虽然剪枝优秀的话还是会省很多时间,但仍然太复杂了。所以考虑再加入 2 来描述状态,我们将填的每一块的每一个部分都钦定一个记录符号,就像下面这样:
这样 DP 就只用记录当前行就能体现整体状况。然后我们从上往下递推转移:如果当前状态当前位置为 1,那么下一行对应位置就是 0;如果当前状态当前位置为 2,那么下一行对应位置就是 1;如果当前状态当前位置为 0,那么下一行对应位置就可以是 0/1/2,注意如果是填 1/2 的话可能会影响后面几个格子填的数,还需要判断这些位置是否可填,然后将方块数量增加一。这个过程可以通过 dfs 实现。这样我们就在放置每个块的第一行时计算了贡献,并且确保放下了完整的块。
这种做法的理论时间复杂度为
总结一下:新的 trick:增加进制数更确切的描述状态,减少状态枚举。递推 + dfs剪枝 大量降低运行时间。
下午先写了 SP16809,对顶堆(维护中位数)预处理 + DP,时间复杂度应该是正解,但是 vjudge 上交不了。又把 P2569 切了,直接根据题意模拟 DP,啥性质也不用找,然后单调队列优化一下就完了。
晚上做 P10965,我怎么突然不会最大 01 矩阵了?看了眼以前做的题才想起来。我们不用枚举矩形的右下角,只用枚举矩形的最下面的一行在哪,然后枚举矩形最高的位置
P4746 是 SP16809 的弱化版,直接交了。又把 UVA1640 做了,简单数位 DP,没啥说的。感觉今天做题量已经超标了,但是这个专题还剩最后一道题:P10968,开始思考。
1.6
上午把 P10968 写了。昨晚初看题还觉得很难,今天一早重新思考,发现按照数字大小插入序列进行 DP 即可,决定写一篇题解。
然后把 P10961 写了,简单 DP 优化,本来还想 bitset 闯过,结果失败了。
下午把 P10964 写了,线段树颜色均摊优化 DP,比较板。发现自己不会 P4954,显然不能直接 DP,需要先发现结论,但是始终找不到什么关键信息,决定看题解。改出来了,代码极短,但是思维还是有紫的,以下是总结:
首先引出这道题的王牌结论:对于同一些草包,在所有堆叠方案中,高度最高的方案一定最下面一层大小最小。因此,局部最优解就是全局最优解。考虑 DP,我们先将
直接做是
关于结论,以下是引用一个陌生大佬的证明: 任意取出一个能使层数最高的方案,设有
构造法证明太强了,显然考试无法证出来,只有猜出结论。我觉得只有多手模,多尝试猜测,多练习 CF 类似的猜结论直觉才可能做出。
晚上把 P4767 过了,就是弱化版再加一个最板的四边形不等式优化。关键在于发现区间中位数距离和满足四边形不等式,这可以通过分讨奇偶性证明,这里不证了。马上下课了,还是看一下 P10966 吧。
1.7
上午把 P10966 写了,比较板,由于四边形不等式写得更熟练些,所以写的四边形不等式。还有一种斜率优化的方法,可以
下午切了 CF1129D,自己切的 CF 2900* !!!感觉有点进步。先用扫描线,然后修改和查询再用分块维护,其中查询整块需要排序和二分,所以时间复杂度为
1.8
昨天晚上打 CF 了。差点调出 D2 掉分了,今天早上很快改出来了。上午还把 E 改了。一开始一直找不到突破口,看了眼题解才发现。又是 CF 比赛的常态:神秘性质+简单算法。具体突破口见 CF 官方题解,关键在于通分合并,转化为 gcd,利用 gcd 的性质:
晚上把 CF2173F 写了。不知道区间长度小于
1.9
今天写了 P11833,去年省选,上午两节课才想到做法(假了两次),下午三节课才写+调出来(太难调了),写了坨 200 行屎山,怎么感觉这道蓝做的时间已经超过了大部分紫题?
晚上 20 分钟把 P11536 切了,历史最快紫(虽然难度显然不到)。本来想水篇题解的,结果交不了了(果然题太水了)。很套路:列式子->ds 维护。然后把 P2163 切了,小容斥+离线二维数点,没什么说的。
1.10
这天被三场线上比赛挤满了。
上午是耻辱场,第一次打 USACO,结果铜组没 ak,被 Ad-hoc B 创飞了,我太菜了!要是没晋级岂不成小丑了?
下午是猎奇场,我不知道为什么自己会去打个洛谷月赛(可能是上午发挥不好精神失常),T1T2 快速水过了,T3 乱搞,不知道哪错了也不知道为什么是对的,反正被捆绑创成了 39 分。T4 也是神题,本想暴力打个 8 分跑路,写的哈希+ dfs,使劲优化+特殊性质,搞到了 44 分。好久没打过洛谷比赛了,等级分一整年没变过了,这回会涨吧。
晚上是雪耻场,abc 从开始就聚精会神,没看过榜单。过了 F 后去看震惊的发现进了 rk100!最后 rk83,表现分 2400,rating +109。然后水了篇 F 题解,等洛谷搬题。
1.11
晚上返校把 ARC180D 切了(其实上周就想到思路了)。一开始一直在想拆贡献+扫描线,结果由于多查询所以不可做。后来想到了答案有关最大值的性质,然后想到用线段树+单调栈维护,然后就解决了,时间复杂度
1.12
昨晚打了 arc,不会 C,今天早上改过并写了题解。关键在于先从绝对值的性质下手,转化贡献计算方法,然后将式子赋予实际意义,再通过插板法计算组合数解决。
下午切了 CF1996G,首先断环成连,枚举从那一条边断开,这样每一条限制就变成了固定的区间,答案就是区间并集大小。优化就列出不等式,转化成二维扫描线,用线段树维护即可,时间复杂度
晚上学习了线段树分治,并写了 P5787。线段树分治与线段树有很大区别,它不用维护什么区间信息,写没有什么修改查询,它只是利用了线段树的二分结构,减少递归层数。在时间轴上建立线段树,可以离线解决像这种在某时刻出现又在某时刻消失的问题。
例如这道题,我们把每条边的出现分配在时间轴线段树上,类似于区间修改。然后通过一次递归找到所有答案,当到达一个节点时,加入新边,如果构成了二分图,那么直接将区间内答案全部设为 no,否则继续递归。递归结束回到这个节点时,将在这个节点上建的新边全部撤销,进行回溯。这就是线段树分治的统计答案方法。
此外,这道题还用到了一个新的知识点:带权并查集(又称种类并查集或拓展域并查集),用来判断二分图。也就是将每个点拆为黑形态和白形态,每次建边建两条,黑白相连和白黑相连,这样就维护了点与点之间的黑白关系。当存在一个点满足黑形态和白形态在同一个集合中,那么不是二分图(因为自相矛盾了)。每次建边时判断两端是否矛盾即可(因为两个连通分量内部一定是满足的,所以只要两端不矛盾,那么连起来后的整个大的连通分量也满足)。这里由于有撤销操作,所以不能路径压缩,需要存储真实父亲,这样又导致需要按秩合并,确保高度。所以总时间复杂度为
1.13
上午切了 CF1924B,比较板的线段树区间修区间查。
然后切了 P1856,比较板的扫描线,直接
下午学习了线段树优化建图,并做了 CF786B。线段树建图主要运用于区间建边的的优化,仍然主要运用线段树的维护区间的结构,将建边区间分成线段树上的
晚上写了 P3919,主席树板子。这道题关键在于想到主席树,因为从题面中你并不能发现需要维护什么区间信息。但是线段树具有二分结构,能够在 log 的时间复杂度下查询位置答案,并且加上可持久化和动态开点,能在 log 的复杂度下创建新版本。所以什么信息也不需要维护,我们只是利用它的结构存储历史版本,不然难以存储(我试过直接链表,但是太混乱了,而且还无法快速查询,还是主席树结构清晰高效)。本来还想再写一遍模板 2 的,但突然觉得自己已经很熟练了,就算了吧。
1.14
上午三节课单挑 abc414g,最后 AC75,TLE2,MLE2,下午发现做法有问题。不能将两边都拆分成线段树节点然后一一连边,因为线段树查询找到的节点个数只是 log 级别的,可能会达到 2log,所以这样连边一定 MLE。
于是先放下这道题,先去把 CF915E 切了,没什么好说的。然后写了 CF1114F,直接用欧拉函数计算方法加上线段树即可,有点卡常,没思维难度。
1.15
昨天晚上突然想到了那到 abc414g 的优化方法,是我犯唐了,忘了个简单 trick 能优化掉一只 log,今天上午改了一点就过了,写了篇题解(虽然可以卡)。看了下官方题解的做法,很巧妙的做法。利用线段树的树边边权,做差分,左边计算终点到左边最大值的距离,右边计算起点到右边最小值的距离,在加上左边最大值与右边最小值的距离,就能得到起点与终点的距离,作差分的过程中始终大减小,因此边权一定不为负。
下午先切了 CF2147F,虽然又不是正解,但是过了。然后写了篇题解。题解区找这个性质几乎都是在图上找的,原来我把分块改成线段树就是正解啊!还有什么组合数学的方法,不想看了。
晚上学习了猫树分治,然后写了 P6240。猫树分治的结构也是和线段树一样是二分结构,但是线段树每次查询需要合并
1.16
上午三节课和下午两节课终于把 P14528 切了,时间复杂度没问题,就是做复杂了,导致常数巨大,但仍然写了篇题解。哦哦哦,原来第一部分不需要线段树,因为没有动态查询,直接倍增预处理即可,我犯唐了。
晚上先把 P7457 切了,我们发现边权很小,所以直接对每种边权都维护并查集检查连通性,询问时从小到大判断是否连通,再加上线段树分治即可。
1.17
上午模拟赛,由于考的是春测题,我做过原,所以被单独换题了。极限切 T4,运用了才知道的组合意义+树形 DP,导致白天心情一直很好。
现在刚结束 CF,心态临近崩溃,被诈骗了 2 个小时,最后 5 分钟才清醒过来怎么做,又要掉大分了。我试图安慰自己,竞赛就是这样,起起伏伏,要学会克服,视之平常,但情绪仍然很低落,毕竟已经连掉 4 场了。哎!
1.18
晚上写了一晚上的英语报纸。
1.19
早上很快把 CF2190B2 改了,比赛时没有发现答案只能为 0 或
然后写了一下午 P9120,由于直接写并集太麻烦了,偷懒写了个容斥,结果被卡常 95 pts,只好面向数据点编程。思维难度有紫,代码难度有黑的一道题。突破口在于观察最小值与最大值所在的行,然后二分答案会
1.20
早上继续写 AtCoder-jsc2019_final_h,中途切了 abc441f。
晚上晚练是唐唐 P3092,然后仍然没有调出白天那道题。
1.21
上午写了对拍,然后终于调出来了,写了篇题解。然后写了 P6864,简单矩乘。晚练是 P5664,做过原,直接写了。
1.22
我不会 P3960,太菜了。线段树综合的不看题解记录就这样被打破了。看了一眼就会了。
晚上晚练是 P3953,没切。
1.23
早上改了晚练题。晚上写了 P3960 的代码。没做出来是因为不会维护操作:从序列中拿出一个元素放到最后。我们只需要在这个位置标记为不存在,在最后一个位置标记为存在,然后使用线段树二分查询即可。加上动态开点线段树,这道题的时间复杂度为
1.24
昨晚打了 CF1075,上分了,还差 24 分上紫,早上来把 E 改了,猜结论题。下午写了 CF2183F,二维计数类树形 DP,还好,我甚至还被卡常了几发。
晚上打了 abc,真的越来越无聊了。把 CF2174D 改了,线段树换树状数组,加上了特殊情况,写了篇题解。
1.25
晚练。
1.26
早上改过了市场,线段树综合做完了,开始做图论例题。切了 P1948,二分答案+01bfs。
然后切了 P3008,之前做了一点。很巧妙的一道题,利用无负环、正边无向的性质,先将每个正边连通分量所为一个点,负边跑拓扑,过程中在连通分量内部跑 dij 即可,时间复杂度
然后切了 P2886,最小环模版。注意不能枚举边,只能枚举点。运用 Floyd 的方法,从大到小加点,记录路径即可,时间复杂度
然后切了 P10928,模拟 kru 算法的过程即可发现结论。然后想 UVA1537,自己想了个构造方法,但觉得可能是假的,感觉正确性不高。看了蓝书,写了出来,本以为会很难调,结果只挂了两发。这里总结一下方法:
首先,发现答案与 0 有关,考虑断开所有与 0 有关的边,使图变成若干连通块。对于每一个连通块,找到它的最小生成树,并从每个连通块中找到最小的一条边连向 0。设连通块个数为
此时我们已经构造出了一棵生成树,如果
这样换边策略就出来了,每次换边时枚举每一条可加的边,找到贡献最优的一条,替换。重复执行以上过程,直到度数顶满为止。至于最后一步的贪心,证明复杂,但是很显然。加强版需用 wqs,这道题直接
然后切了 P10929,简单最短路计数。
1.27
昨晚晚练炸了。早上切了水紫 P3629。然后切了 P10931。复习了一下线段树合并,理解了以前对复杂度的疑问。
空间复杂度:观察发现每个树节点会产生一个线段树的根,共有
时间复杂度:update 函数时间复杂度
下午调过了 P1600,结果发现根本不需要用线段树合并,直接差分即可。就当复习了吧。开 P10930,只会劣且暴力的树剖,双
做法是将黑点按 dfn 序排成环,两两之间距离之和就是答案的两倍。为什么呢?蓝书上说“细心的读者可以发现...”。这太水了。
为了解决,我们先看到双倍经验 P3320。我们发现,最优路径一定是以一个黑点为根,然后对所有黑点进行深度优先搜索,经过的总距离就是答案。那么怎么确定经过点的顺序呢,考虑按 dfn 序排序,构成一个环,累加两两之间的距离。但是根节点不同,dfn 序不同怎么办?初始时以 1 为根计算 dfn 序,之后排序时就用这个 dfn 序,容易发现无论以哪一个节点为根排序后的环形都是相同的。维护就很简单了,用 set 维护排序后的序列,增删元素时对应增减贡献即可,两点距离用 lca 计算。再回到本题,我们发现这道题的边集与上述路径相同,只是由于 dfs 时每条边会被计算两遍,所以答案除以二即可。
1.28
上午切了 P1084,昨天题读错了,以为是每条边的两个端点都需有一个检查点。今天重读题后发现倍增部分很简单,难点在于根节点儿子的分配方法,仔细思考贪心策略后解决。总时间复杂度
然后切了 P4381,基环树一眼题。对每课树求直径和最长链,然后对于每棵基环树,在环的位置合并树的最长链可以使用单调队列维护滑动窗口最值。总时间复杂度
切了 P6066,欧拉回路模板。
下午做了 P2868。做之前先学习了分数规划,很简单巧妙的一个 trick。考虑到无法直接计算这种式子的最值:
然后切了 UVA1723,简单差分约束。复习了下割边割点和欧拉路径。原来求欧拉路径的算法其实很容易理解,就是使用栈的数据结构,不断对一个栈顶节点进行扩充环的过程,由于回溯时才会加这个节点,所以求出来的序列就是倒序的欧拉路径。
1.29
放假了。整天几乎啥都没干。
1.30
昨晚 CF 上紫了。返校了。
1.31
MX NOIP 集训。快速切了 P2801 和 abc174f。然后学习了普通莫队。有意思的算法,平面直角坐标系上走点是一种很好的理解方式。过了板子 abc405G。切了 P4462,板子。晚上写了 P5356,一开始只会
1 月结束了。