-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.json
1 lines (1 loc) · 107 KB
/
search.json
1
[{"title":"CF1876C Solution","date":"2023-10-09T00:02:52.000Z","url":"/2023/10/09/CF1876C-Solution/","categories":[["undefined",""]],"content":"给定一个长度为 的序列 。 你可以对这个序列进行任意次操作,每次操作选择一个下标 ,并圈住下标为 的数 。可以多次圈一个数。 请构造出一组操作方案,使得操作选出的下标序列 等于没有被圈过的数构成的序列 。 请注意,下标序列和没有被圈过的数的序列皆有序,后者按照原序列顺序依次排列。 假设我们令操作序列为 ,未被选中序列列为 。 初看题面,有一个很重要的信息:操作选出的下标序列是唯一对应的。 即,要使 ,则第 次选择的位置唯一确定为 。 那么我们可以发现,要是某一个数 要是不选,那么就只有唯一确定的 的位置要被选中,并且选择的顺序要对应上 的位置。 并不需要考虑位置对应的事,因为一个数刚好只会对应一个操作。 反过来思考,要是某个位置 要是选中了,那么就一定会有不小于一个的 被留在了不圈出的序列里面。 考虑抽象成图论问题。每一个数抽象成一个节点,那么变成了黑白染色问题。 令圈一次以上为黑色 ,令不圈为白色 。连边 ,以上说法可以转换为以下的涂色问题: 白点后面唯一的出边到达的点必须是白点。 一个黑点的所有入边的起点中,至少有一个白点。 关于样例的涂色方案是这样的: 发现这刚好是个内向基环树或森林(每个点只有一个出度,并且环外指向环内)。 考虑在环外跑拓扑排序,依次染色,发现叶子节点必然是白色,那么考虑以下的染色方案即可跑完不含环的部分: 一个点是白点,则指向的节点必然是黑色。 若一个点儿子被拓展完进入队列时还未被染色(即所有儿子都是黑色的),那么染成白色。 图示:(黄色为白,红色为黑) 这样构造是唯一的部分合法的(不那么构造不可能合法)。 把非环的部分跑完,考虑跑环。 如果环上有被染色,那么可以证明一定是黑色。(白色的要求是儿子全部遍历完,那么环不可能遍历完所有儿子进入队列) 两种假设: 要是环上全部没有被染色,那么从任意一个点开始,染成白色(染成白色是不会出现冲突,因为要是冲突会一定被染成黑色,就有部分点被染色了)。 要是环上有点被染色,从任意一个点有颜色的点开始。 开始后按照非环部分一样拓展。有一点小特殊,但也有一般性的是:当前点为黑色,下一个点并未被涂色时给下一个点涂为白色。 涂一圈,判断是否合法的便是在最后看首尾两个点颜色情况了。黑色和黑色撞一起是可以的,因为既然染成了黑色就一定有白色作为起点。但是两个白色就不行了。 最后检查所有白色点,对应到的就是不被选的点,找出它们对应的 ,全部依次推进答案中,输出即可。 一点小细节,环可能不止一个。 "},{"title":"2023-2024 OI 日记","date":"2023-09-17T08:52:04.000Z","url":"/2023/09/17/2023-2024-OI-Diary/","categories":[["undefined",""]],"content":"同步于 个人博客 ,欢迎前来访问! 09-16 csp 第一轮。 早上没定闹钟,起晚了。 路上遇到了中考屏蔽大神,他为我加油了,rp 攒到了)到机房已经接近 650 了。某人已经到了。 隔壁机房陆续走掉了,压力上来了)) 深渊重置,打了深渊,原石 +600。前瞻,+300。每日,+150。总共一千左右,上车抽卡(剧透:歪了刻晴)。 大伙都来了,开摆,总之摆了一上午。 中午去吃饭,非常上火。 睡了半个小时觉,准备出发。 车上歪了刻晴。别人没歪。 久违的只因中,新科学馆竟然没有饮水机! 抱着水杯跑到别人高二教学区灌水,赶回来了。 进考场发现周围一堆熟人。感觉前后都很强,想开摆。发答题卡,检查了三遍准考证号。 开考。单选做得贼慢。霍夫曼树是什么东西??16 进制的 “9” 整除问题?? 阅读理解。位运算是什么东西?一开始看错了,没有使用异或后的东西再次异或。幸好发现,总计 5 分挽回。数论???不会,手算,还算错了,但是好在数组理解正确。不理解时间复杂度。分治??? 完形填空,还剩下一个小时?还是半个小时。反正做完的时候还有 6-7 分钟。检查检查,把 选择题 14 题从 B -> C -> D。 好,结束了,开摆。 对了答案,大约有 80 pts?,车上直接开 phi。然后被难度劝退。 晚上和机房的几个大神出去吃饭。整了一圈才拿到币!只是可怜了另一个没来的人 wj。玩了一圈下去吃姚。结果大家都没怎么吃/dk 我选错了/dk 非常愧疚/dk 然后又随便逛了一会儿就打车回家了)挺好的一天! 09-17 周末。 早上被某人叫起来,我真厉害。赖床综合症 早上唯一干的事情就是原神。我真摆。 是周日,提早返校。我还记得周日是领导多倍经验日。今晚不能太摆。竟然吃到了 wls 的瓜! 所以,18:30 被迫回来打日记) 突然发现每天写点什么也没啥问题) 初赛感觉压力还是有的,但是考的还可以,我觉得归功于这几天确实颓废变少了。说明,内卷是必要的/ll/ll/ll/ll 接下来两个月的停课,还有两个月就要滚回 whk 了,希望在滚回去的时候回看这段内容不会后悔。 顺便膜隔壁机房的各方大神,stO ljw Orz stO zzh Orz stO ScatteredHope (帮我记住了 Scattered 的大神)Orz stO 其他不知道名字的 Orz stO ryanright Orz stO tsz Orz stO WBWYX Orz stO wj Orz stO tigerhan7 Orz stO lqw Orz stO 陈总 Orz stO 其他以及退役的 Orz。 所念皆星河。 09-18 摆大烂的一天。 补了点 noip 计划的作业,专题并未进行,感觉有点摆。总结了一下,我应该调整一下做题的方法,应该在思考 20 分钟后开题解,有些题目思维你想不到就是想不到,还不如积累下经验多做点题/lh 晚上打 cf,打的还挺好,Div1 + Div2 总计做了 4 道,罚时 *4,A 一次,D 三次。D 的三次罚时本来都是不太应该的,原因是当时觉得这个做饭正确性不是那么显然,所以就有点摆烂,没有好好检查细节就提交,以后提交的时候应该要更加谨慎。 09-19 Rating += 110. 早上有人叫我的感觉真好) 早上起来属实困。一个早上共计学了一个算法 + 一道数论;补了以前的题单,做的不是特别多吧,因为确实有点困,啥也想不出来; 睡了一中午,起身想期望 dp。推了一个 的做法,打完过了部分分之后发现好像不是特别容易优化。 于是就摇到了 @WBWYX @Small_Tang 两人,进行了一波激情推导,最终因精度问题使用了面向数据的做法水过了这道题。 (式子极其答辩,如果想看的话可以来找我要)) 晚上还是好困,有点头疼,躺了一会儿,总之晚上有点摆。 感觉每次熬夜之后第二天就得摆烂了,得想个办法解决这个问题)"},{"title":"斜率优化 dp 学习笔记","date":"2023-07-14T02:35:53.000Z","url":"/2023/07/14/dp-slope-optimize-study-notes/","categories":[["undefined",""]],"content":"斜率优化,一个挺陌生的词汇,在 OI 中应用不是特别广泛,作为 dp 难题的形式出现在压轴位置上。 基本思路是通过对线性递推式的变化使之符合一个直线,并将最小/大化问题转化为截距最小问题(不着急,以后提及)。 如例题 「HNOI2008」玩具装箱。 在这道例题中,根据题面可以得到递推式: 这个式子是 的,递推下来是 。 为了优化降低复杂度,尝试拆开这个式子(设 ): 提取出与 无关的东西放到左边, 也就是说,现在要最小化的仅为右边的这部分( 是可以出 的因为与 无关)。 令左边为 ,,(拆开来是 。 全部带入原式,变成了: 也就是说,变成了最小化函数 过定点 且斜率为 的最小截距(y 轴交点最小化)。 首先,斜率仅关于 ,是定值;因此可以想象一个个平行的斜率过不同 的点时的不同位置(斜率和过点可以确定直线)。 想要找到最小值,那么直观的说,就是要找到在最下面的直线。 一系列 的点构成了一个下凸包。 如果选择的点不在下凸包上必定不是最优解。 鄙人很菜,不会证明,只会臆测。理论上来说应该是正确的。 减少了很多点,现在只需要判断凸包上哪个点时最合适的。 由于是下凸包,斜率 严格非降,亲自移动一遍,应当某个点使左边的斜率比直线小,右边的斜率比直线大会在向上移动时刚好第一个碰到直线,是最优解。 由于斜率 在移动 时是递增的( 不降)所以,夹在两个直线之间的点只会向后移动不会向前,那么这时候就想到了单调队列。 用单调队列维护相邻两个点的斜率 ,非降,因此总 维护这个最合适的点,均摊就是 。"},{"title":"树形 dp 学习笔记","date":"2023-07-10T06:30:07.000Z","url":"/2023/07/10/Tree-DP/","categories":[["undefined",""]],"content":"虽然树形 dp 并未在一大论文之中获得一席之地,但是却无时不体现出 dp 与记忆化搜索的联系与结合。 简单来说,树形 dp 指一类发生在树上的状态转移与优化问题,与一般 dp 问题拥有类似的特征,分阶段,有状态,只不过阶段为层数,状态为节点。后效性与子问题需要着重考虑,不然可能出现设计状态出错的问题。 拿例题说话。 P1352 没有上司的舞会 这是一道树形 dp 模板题。 首先,每一个子树相互独立,互不影响,所以无后效性,且保证了子问题最优的要求。 其次,设计状态,每个节点作为一个状态,代表了子树的最优情况。 但是题目有特殊要求,员工选了就不能选他的直接上司。为了保证状态的准确,增加一维,表示此位置有没有选择,以决定上层的上司能否选择。 因此,可以得到树形 dp 递推式: 记忆化或直接递推皆可,下面给出示例: 多倍经验:P2016 战略游戏; P2015 二叉苹果树 题目大意:删掉一些枝条使边为题目要求 + 仍旧联通,保持树的性质,且边权和最大。(要求必须要有根 1) 由于保证了树必然是二叉树,且每个节点要么满要么没有儿子,所以直接对儿子进行枚举。像方才那样设计递推式,将第二维改成已经选择了多少个边,之后向上递推,完成 dp。 按照这个做法完成这道题目时间绰绰有余。 但是,对于这道相似的题目,却完全不一样了。 P2014【CTSC1997】选课 题目大意:对森林中每棵树选择一些对应拓扑顺序节点,使所有节点数量符合要求,且权值最大。 在这道题中,并未保证每个节点的儿子情况,甚至是森林,导致在节点中枚举鸽节点中情况过多,每个节点枚举代价太高。 因此,考虑如何优化每个单独的节点的情况。 一种很新颖的做法,dp 套 dp。 这么多选择,其实就是背包对容量的很多选择,和 01 背包是一个道理,只不过对于每个物品都有 1 ~ m 种可能,多枚举一层。 隐去一维,树 dp 夹背包的递推式为: 边界为 。 共三维,故 。 P4316 绿豆蛙的归宿 初看这道题似乎挺麻烦的,还得找所有路径对应概率乘积求期望。 但是,画几个草图就能发现,每条边的贡献与选择的路无关,只和自身的位置和父亲节点有关。 那么就能将概率递推求得,再用概率乘上边权,加起来便是总的期望。 P1273 有线电视网 多倍经验,与《选课》类似,树形背包。但是要注意循环内枚举顺序与范围优化,否则滚动/时间是不正确的。 需要注意的是,这道题目中,背包容量不能设置为边权。选择不同的起始点会影响到后来的选择,而且边权之和可以为负,不好处理且空间爆炸,因此可以转换思路,改成以个数作为容量,后面从大到小判断并输出。 P2656 采蘑菇 图上 dp。DAG 上最长路模板,dp 可做到 。 大概思路,缩点算点权后在 DAG 上求最长路即可,数据范围不大,所以怎么搞都行。 需要注意的是,最好重新建图,否则容易混乱,导致我调了近一个小时。 以及精度问题,这道题虽然仅有小数点后一位,但是涉及到小数变整数的截取操作,因此要加 eps,不然会出现实际上 1 但是在内部存储了 0.9999999999 然后向下取整截掉了。 P2585【ZJOI2006】三色二叉树 题目不难,主要考察了树的表示方法(模拟)和一个很简单的三状态树上 dp。 对每个点设计状态表示当前点颜色,开两个数组表示最大最小。 没什么细节,不知道为什么能上蓝,是因为出题人是【洛谷】吗。 P2515【HAOI2010】软件安装 依赖背包,以前没填的坑,今天终于填了。 简单来说,就是利用树来限制转移的源和目标,使父亲节点必须要被选上,然后再在树上做一个树上 01 背包即可。 细节挺多的,比如说,有可能某些软件互相依赖,本来以为题目保证了是无环图,但是看讨论区才注意到,重构了一遍,加入了缩点; 重建图的时候一定要把那些与 0 无关的点连上,已经连了就不能连了,多连会出事。 拓扑到某一点时,需要先单独将该点的权值做一遍和先前做过儿子节点的 01 背包,因为不能跟儿子节点一起做,否则就会算重。 在拓扑排序中顺便把 dp 以向外扩散的方式递推出去,不选择当前节点的那些容量位置因为被滚动下来了要重新置为极小值。 最后取答案只取 0 上的答案,dp 会搞定一切。 debug 挺麻烦的,最好一遍过。 思维绿,实现紫? P2986【USACO10MAR】Great Cow Gathering G 找树的带权重心,而且是边权点权一起有的那种。 套路树形 dp,先预处理子树大小(加点权),顺便把 (选择在 时的总代价)算了。 再从 开始,向下递推,式子为: 是上方点数量, 是下方点数量,其他自行理解。 实现不难,好像要开 long long?不知道不管了,反正加了又不会 MLE。 "},{"title":"DP 技巧学习笔记","date":"2023-07-05T02:23:18.000Z","url":"/2023/07/05/DP-Study-Note/","tags":[["笔记","/tags/%E7%AC%94%E8%AE%B0/"]],"categories":[["undefined",""]],"content":"动态规划,顾名思义,就是对决策进行动态的规划。 动态规划的两个必要条件: 最优化原理 如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。 如,在 dp 递推层次图的最短路时,最优解路径上每一次转移必然是最优的(在子结构中,就是在当前的状态下的最优解,和自己比不和别人比)。 当遇到题目在最优解中可以不选择最优的子结构时,就不满足最优化原理,也就不是动态规划问题了。 无后效性 即子问题的解一旦确定,就不再改变,不受在这之后、包含它的更大的问题的求解决策影响。 即不走回头路,在上面的例子中,你选择了某一条边,之后的决策都不会影响到你选择这条边的最优解性,这就是无后效性。 在有了必要条件后,就需要设计决策与状态。 dp 的主要过程,就是 状态 – 决策 -> 状态 – 决策 -> 状态。 需要保证 dp 时间正确性的,是状态的维数和决策的复杂度。 以一道经典 dp 为例:P1854 花店橱窗布置 题目中,每一朵花只能选择一个花瓶且互不干扰,满足无后效性,且题目中的最优解为子问题之和,需要最优化原理。 因此首先可以判断可以使用 dp。 设计状态:两个思路,一是每个花瓶的状态,二是每个花的状态。 最直接使用题目的要求(花要按顺序放)的方法,对于花的状态,可以用第二维记录上一个花瓶的状态。 转移方程:。 如果将花瓶作为状态,也只需要按次序放花即可,只不过需要处理有些花瓶可以不放置花。 “这个例子具有很大的普遍性。有很多的多阶段决策问题都有着不止一种的阶段划分方法,因而往往就有不止一种的规划方法。有时各种方法所产生的效果是差不多的,但更多的时候,就像我们的例子一样,两种方法会在某个方面有些区别。 所以,在用动态规划解题的时候,可以多想一想是否有其它的解法。对于不同的解法,要注意比较,好的算法好在哪里,差一点的算法差在哪里。从各种不同算法的比较中,我们可以更深刻地领会动态规划的构思技巧。” 动态规划设计模式 动态规划的设计都有着一定的模式,一般要经历以下几个步骤。 划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。注意这若干个阶段一定要是有序的或者是可排序的,否则问题就无法求解。 选择状态:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。当然,状态的选择要满足无后效性。 **确定决策并写出状态转移方程:**之所以把这两步放在一起,是因为决策和状态转移有着天然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。所以,如果我们确定了决策,状态转移方程也就写出来了。但事实上,我们常常是反过来做,根据相邻两段的各状态之间的关系来确定决策。 **写出规划方程(包括边界条件):**在第一部分中,我们已经给出了规划方程的通用形式化表达式。一般说来,只要阶段、状态、决策和状态转移确定了,这一步还是比较简单的。 在某些动态规划应用中,阶段并不明显。甚至有在设计的阶段之中转移。 可以总结,状态转移一般是在相邻的两个阶段之间(有时也可以在不相邻的两个阶段间),但是尽量不要在同一个阶段内进行。 P1220 关路灯 题目大意:在区间上最大化数轴上的数 * 移动距离。(原题:最小化总和-数轴上的数 * 移动距离) 划分阶段:区间 dp 按照区间长度划分阶段 选择状态:记录区间左右端点位置,并且记录 0/1 记录结束状态(由于最大化,所以每次必然是向左向右依次点灯,这里去掉了那些不合理的移动,最终就只会停留在左端点和右端点。 状态转移方程: 其中 pre 为数字前缀和,ps 为数字位置。 边界:。 启示:不能局限于一种思维,做 dp 时要将思维打开。 例题: P1833 樱花 多重背包,正好复习一下。 拓展背包问题的一般做法都是替换;将无限物品和有限物品替换为一个单独的物品,只是代价翻倍。 对于个数限制为 的物品,要分解为不超过 且 都要覆盖到,可以这么分解:。 分解后直接套 01 背包。 P1725 琪露诺 经典的单调队列优化线性 dp。使用单调队列 维护滑动窗口。 P3842 [TJOI2007] 线段 一道有意思的简单线性 dp。不难的状态推导,不刁难人。 P1775 石子合并(弱化版) 区间合并模板, 的应用。 P1352 没有上司的舞会 树形 dp 基本模型。 思路:在树上递推。首先寻找根,推式子:,。 以记忆化搜索的形式书写, P1122 最大子树和 树上贪心?为什么会跑到 dp 题单里; 对每一个子树统计子树和,如果是负数,那么不选择这个子树是必要的。反之,是必要的。 而有可能出现剪掉上面枝条的可能,所以在路上维护子树(非负树叶枝条)的最大值,一并算到 ans 中。可以证明是维护到了所有的情况。 P2016 战略游戏 类似于没有上司的晚会,只是代价最小化和代价全为 。 P1874 快速求和 类似于背包的线性 dp,看上去像区间 dp,但是和区间合并关系不大,且状态只和到当前节点的数值和到了哪有关,所以直接二维线性 dp。 P3147【USACO16OPEN】262144 运用了一点倍增的思想(因为是合并问题)。 思维路程:因为合并而想到区间 dp。发现区间 dp 由于范围太大好像不太现实;突然发现合并的数并不大,有没有可能把数作为一维当作状态? 可以发现,对于每一个数值和一个起点,必然有唯一的一个最小的右端点使左右端点覆盖的区间可以构成这个数值(这里要求必须要用到边界,否则就不一定能相邻的合并了,一开始没想到也是因为怕没用到边界)。 那么发现左右两个相同的数值的区间好像可以合并? 写出递推式: 数值为 ,左端点为 时,通过第一次取用 寻找 的最小区间;如果可以找到,那么再次寻找从该位置开始向后一位的构成 的最小区间位置。无论寻找不寻找到,都回去更新 。 发现好像刚好能够继承左右边界都用了的条件,那么就可以 dp 了。 这道题思维也算挺有意思的。 P2340【USACO03FALL】Cow Exhibition G 一个互相依赖的背包问题,要求两个权值和都要大于 0。 很正常地想到了二维,将这个两个权值都并了进去,但是好像值没什么用了; 那么将其中一个权值变成数组的权值,加入一个序号 , 表示在第 头牛智商为 时情商的最大值 。两个值互不影响,最终算答案时只需要简单枚举筛选即可,这个设计方案非常聪明。 只是,由于 的可负性,而且范围还挺大的,挺难处理的,还需要加上 。 实现比较复杂,感觉不止黄。 CF149D Coloring Brackets 染色区间 dp,大致题意是给配对的括号分别染色,符合题目要求的染色方案的总数。 括号->区间 dp; 通过中点转移的方式分割序列,确定递推顺序,使用搜索确定拓扑序。 P6835【Cnoi2020】线形生物 期望 dp,做的很少,好不容易做一次。 积累的经验: 设 为 需要经过的期望距离,这样就可以表示 为 。(前缀和,原因是期望的线性性质,可以直接相加) 使用期望公式,,可以得到一条式子,通过将与 有关的全部放左边,其他的全部放右边,整理就可以得出一个可以递推的式子。 期望题目不要老想着数学做法,尝试 dp 套公式推式子做递推。 P2051【AHOI2009】中国象棋 二维 dp 很新颖的题目。 考虑每行枚举,向上通过统计上面一行状态来转移下面的状态。这种方法适用在不好统计重复的状态贡献(因为如果直接二维 dp 的话就不好控制两个方向上互相影响的贡献)。 "},{"title":"0-1 思维学习笔记","date":"2023-07-04T01:42:10.000Z","url":"/2023/07/04/0-1-study-note/","tags":[["笔记","/tags/%E7%AC%94%E8%AE%B0/"]],"categories":[["undefined",""]],"content":"二进制思想在信息学的实践,是无比重要的。 1. 树状数组 使用了民用计算机补码的性质,使树状数组移动的常数小且空间小,且易实现,代码简单。 总的来说,树状数组应用了线段树维护区间的思想,将区间二分为块,每次修改和查询只需要修改 个点。 只是,树状数组实际上维护了一个二分的前缀和数组,而并不是维护区间。 在查询时使用前缀和的性质求解。 所以树状数组只能维护有结合律的运算。 在树结构上与众不同,使用了二进制的特性。 树状数组的节点编号是树状数组的精髓,如下图 编号从 。 假设要查询 ,从编号 开始。 计算 ,那么如何计算 呢? 向左上跳,跳到 。加起来,就是结果。 事实上,树状数组的树形态是 向 连边得到的图,其中 是 的父亲。(边是修饰,实际上不需要连边,这也是树状数组的一大特色:简洁) 树状数组运用了位运算的性质,可以方便地求出当前 的范围,不重复地计算前缀和。 单点修改,只需要像查询一样,不过要向右跳,为什么? 因为部分前缀和 只向前统计,修改了 只会影响到 。 有了 ,树状数组变成了这样: 典型应用:二维树状数组。 2. 状态压缩 当状态维数很多,但是只考虑取舍时,可以考虑状态压缩。 以后补坑。 3. 01-Trie 是一个简单轻巧的结构,结合了 Trie 的特点,适合运用在优化二进制题目中。 见字如面,字典树,就是储存字的典树。 Trie 利用树前缀存储方式存储字,而像 01-Trie 这样只有两个关键键值,Trie 的空间优势和深度优势就显示了出来。 比如说: 题目描述 农民约翰在喂奶牛的时候被另一个问题卡住了。他的所有 个奶牛在他面前排成一行(按序号 的顺序),按照它们的社会等级排序。奶牛 #1 由最高的社会等级,奶牛 #N 最低。 每个奶牛同时被赋予了一个唯一的数 的范围内。 帮助农民约翰找出应该从哪一头奶牛开始喂,使得从它开始的某一个连续的子序列上的奶牛的数的异或值最大。 简化题面 已知一个数列 长度为 ,求数列 子串异或和的最大值。 输入格式 第一行一个整数 ,表示奶牛的数量。 第二行 个整数,表示奶牛的数 。 输出格式 一行一个数字,所求得的异或和的最大值。 这道题目是经典的二进制贪心。 将异或前缀和,就变成了寻找两个值异或的最大值。 而选出两个值使异或最大,又由于二进制的贪心性(优先选择高位,即 ),可以考虑建立一颗 01-Trie 维护所有的值,对应每个值贪心寻找最大的数。 详细一步说,双指针,每次向下探索时都观察能不能和选出的数反着来(异或)。由于贪心,不需要考虑后续,正确性可以保证。 01-Trie 高度为 ,因此 。 Trie 应用题 P2580 于是他错误的点名开始了 Trie 模板,但是需要注意空间问题。 P2922 [USACO08DEC] Secret Message G 难度不高,也算是 01-Trie 模板题,不过要注意题目描述,不然可能获得不到 分的好成绩。 P4551 最长异或路径 一道思维题,加入了第一道模板题的思想。 主要是运用了异或的自消性,只需要随便找个根,转换成前缀和,其他所有都搞定了。 不过虽然数据不会爆 int,但是有时候左移多了正好就爆了。 二进制题目不多,就先扯到这里。"},{"title":"P9308 Solution","date":"2023-05-10T11:44:28.000Z","url":"/2023/05/10/P9308-Solution/","categories":[["undefined",""]],"content":"「DTOI-5」#1f1e33 令 , 着手解决 。 考虑整理 后面这一坨东西: 这坨可以 ,然后考虑后面的东西。 设 则上式化为 这一部分可以整除分块 做? 乘上前面的 ??"},{"title":"数论定理公理大全","date":"2023-05-10T11:34:24.000Z","url":"/2023/05/10/Math-All-in-One/","categories":[["undefined",""]],"content":" 莫比乌斯反演(中心定理?) 则 GCD 1 GCD 2 GCD 3 GCD 4 "},{"title":"初赛自创填空题","date":"2023-04-14T05:33:03.000Z","url":"/2023/04/14/fill-problem/","tags":[["初赛","/tags/%E5%88%9D%E8%B5%9B/"]],"categories":[["undefined",""]],"content":"实验室中有一个由 个实验腔连接而成的环形轨道,其中第 个实验腔顺时针连向第 个实验腔(特别的,第 个实验腔连向第 个实验腔)。同时还有一个标号为 的新建实验腔要接入这个环形轨道。它可以接在任意两个原本相连的实验腔之间。 第 个实验腔可以将带电荷量为 的粒子运输到它的下一个实验腔,这个过程花费的能量为 。除此之外,第 个实验腔本身就存储了量为 的电荷(电荷量有正负)。由于众所周知的电荷守恒定律,第 个实验腔储存的电荷量与前 个实验腔储存的总电荷量的代数和为 。 小 Z 有一个原本不带电的粒子。等到第 个实验腔接入轨道后,他要任选一个实验腔(包括第 个)作为出发点,将粒子放入,并使之在实验腔的能量驱动下顺时针环游一周回到出发点。粒子每到达一个实验腔(包括出发点),它所带电荷量就会变成原来所带的电荷量和这个实验腔所储存的电荷量的代数和。 注意:电荷量会先加上实验腔所含电荷量,再计算能量贡献。 现在,小 Z 想知道,在所有接入新建实验腔并选定出发点的方案中,粒子环游一周所需的能量最少为多少? 提示: 本代码做法是维护一个 和 之后用二分寻找分界点 后直接统计。省略了读入和输出函数 read 和 writeln。 A. c * s B. c * s * pos C. s D. s * pos A. nds[nds[u].lc].c <= cpos B. nds[nds[u].rc].c <= cpos C. c + nds[nds[u].lc].c <= cpos D. c + nds[nds[u].rc].c <= cpos A. (lc - rc) * qs + rx - lx B. (lc - rc) * qs + lx - rx C. (rc - lc) * qs + rx - lx B. (rc - lc) * qs + lx - rx A. s[i] + e[n + 1] B. s[i] - e[n + 1] C. s[i - 1] + e[n + 1] D. s[i - 1] - e[n + 1] A. n * 2 + 1 B. n - 1 C. n D. n + 1 "},{"title":"这种题都要别人帮忙做的是屑","date":"2023-03-24T11:16:52.000Z","url":"/2023/03/24/the-one-who-ask-other-for-this-kind-of-problem-is-xie/","categories":[["undefined",""]],"content":" "},{"title":"solution-arc026_4","date":"2022-11-12T03:28:31.000Z","url":"/2022/11/12/solution-arc026-4/","tags":[["题解","/tags/%E9%A2%98%E8%A7%A3/"]],"categories":[["undefined",""]],"content":"arc026_4 题解 翻译: 有 个村庄,编号从 到 。这些村庄通过 条道路构成一个连通图。 有一天,一场大规模的灾难摧毁了所有的道路,使得村庄之间的交通无法进行。你需要修复一些道路,将这几个村庄连接起来。 您首先估计了修理每条道路所需的费用和时间。然后计算出最低小时工资。 「小时工资」是指「修路所需费用的总和」除以「工作总时长(单位:小时)」,即 请注意,不一定要修理所有的道路,也可以修理不需要的道路,只要将村庄连接起来即可。 保证图联通,且没有自环,重边。 根据题目的描述,一条边对 的贡献的多少,可以用 衡量吗? 也许,在一定程度上,是可以对比两条边的贡献。 于是,一开始我便想到一种做法,选择所有 的边,剩余的边再以 比较跑最小生成树。 能保证正确性的一个显然的结论是: 的所有边总对于贡献为负。(就是能够让 尽可能小) 但是,这显然是错的。反例:对于一条边 , 为什么?有一条式子(不妨 ,等号同时取): 代入到 的变化,同时设 ,条件是 (同 )。 由于题目并未保证 ,所以有可能有 。 所以有: 观察到 (结果变大了,贡献非负)。 所以并不是所有 的边都对贡献为负,还需要判断当前 与 的大小关系等。 考虑到这不好维护,转换以下思路。 不能够通过 来判断边之间的贡献情况。注意到 ,可以容下 。 如何将判断贡献转换为整式的判断呢? 考虑二分最终 。 但是,我们如何判断一个 (简称为 ) 是否能够被构造出来呢? 由于我们的目标是判断是否能构造 。 , 那么,处理为整式之后,只需要判断当前选择 之和是否小于等于 即可。 通过这个变换可以将判断目标变为正负代价的简单判断。 对于每一条边,我们让 整合代价 。 若 为负,必然对最终的总代价是好的(目标是非正数嘛)。 那么就可以对边按 排序,选完所有 非正的,最终对正数跑最小生成树即可! 如果跑出的生成树结果与之前选择负数贡献边的贡献之和小于等于 ,那么必然可以构造! 注意!这里的判断只能判断对应 能否构造出更小的结果(即只能获得上下界信息),所以才只能二分。 时间复杂度:。()"},{"title":"2022-10-26 review","date":"2022-10-26T12:26:08.000Z","url":"/2022/10/26/2022-10-26-review/","categories":[["undefined",""]],"content":"书接上回。 因为疫情的停课已经结束。还算不长把就两天还可以接受 中段考后移至 2022/10/30-31,与预期一样。 但是,有喜讯是,可以在中段考的时候继续停两天的课。 这些是小事的牢骚。 以及,昨天的校内赛。 T1:STL sort 大赛。-> cmp 打假,挂 100pts T2:假做法,但是有 95pts!-> 挂 5pts T3:过了 XDDD T4:根本没看 所以啊,倒数第二次考试考成这样,蓝勾~~ 以及,明天又要校内赛了。希望是信心赛。 停课两三天就结束了,文化课又开始了/ll /ll/ll/ll 离退役,还剩 2 天。"},{"title":"高斯消元法 笔记","date":"2022-10-24T02:27:51.000Z","url":"/2022/10/24/Gauss-elimination-method-Jordan/","tags":[["数学","/tags/%E6%95%B0%E5%AD%A6/"]],"categories":[["undefined",""]],"content":"例题:[NOIP2004 提高组] 虫食算 在这道题中,我们要解一个多元一次方程组,即对于 这样的数式计算,要找到所有字母对应的数值,使对于这样的 进制加法成立。每个字母对应一个数字。 很容易可以转换为方程组。问题就在于,如何解多元方程组? P3389 【模板】高斯消元法 答案就是,高斯消元。 做法 首先,可以把一个多元方程转换为一个矩阵: 想象平时解一个多元方程时使用的方法:消元。 那么如何对一个多元方程进行消元呢? 高斯消元选用加减消元法。 想象一个方程: , 于是方程变为 通过这样的变形,方程组将变成一个好看的形状——斜三角形 /kk。 观察到,在这种形状中,第 个方程中,所有 的 系数都为 。 这样的形状有什么用呢? 最下方的式子形式为 ,可以获得一组解; 通过代入的方式,倒数第二行的方程 由于已经知道了 的解,可以直接带入求 的值。 通过带入和消元,最终将会把所有方程全部消干净,于是就能得到多元方程的解。 将方程化为矩阵,上面的例子可以解释为这样: 对矩阵进行初等变换, 可以变成这样子 只要将矩阵化为左下角全为 就肯定有解了。 那么,问题就在于,如何把这一并非非常客观的过程转化为代码实现呢? 实现 要得到一般规律,我们需要寻找一个普遍的实现,来对这个实现进行总结。 观察第一次变形。 由于倒三角形式(简化阶梯型方程组)的要求,必然有 行及之后的所有第 列之前都是 。 比如说当 时,第二行及之后的所有行的第一列要求变成 。 那么如何做到这一点呢? 每次按顺序(从 开始)依次选中 ,对于所有 行及之后的所有行进行加减消元。 由于是依次进行消元的,所以选择第 行进行加减消元,理由是刚好比下面所有行都多一个系数(因为 ta 在前面消元的过程中已经消掉了 及之前的所有系数。如: 现在已经完成了第一轮消掉 的过程了。 那么如何对于第三第四行依次消掉 的呢? 选中第二行,刚好比下面都多要求保留一个系数。(在这一次中第二行不变,因为已经满足条件了) 必然可以通过乘上系数的方式使得 (这样就能通过做减法消掉系数)。 就如上面的例子,第三行乘 ,就变成了这个样子: 于是做减法。 为什么会出现小数呢(反而上面的示例没有)? 因为上面是手算——为了避免分数而调换了行之间的顺序(其实差不多,对于电脑来说,只不过是浮点而已)。 况且有些时候解必然是浮点数。 第四行同理,乘上 , 变成 做减法, 那么将会又消掉两个数! 不断的进行下去,就可以获得解! 还有一个问题。如果在消元的过程中出现上一行的第 个数字刚刚好为 ,那么很不走运的,这一个方程并不能用来做消元。 那么该如何调换各个方程之间的顺序,使得每一次操作的时候都有一个方程可以去加减消除掉? 可以在对每列做消元的之前做个预处理。 对于每一个 ,都要保证 。 如果出现 ,那么就需要找一个 。 于是可以寻找 。 (为什么这里 下界 为 呢?因为不能够动前面的方程啊,不然前面就不满足条件了) 这时候就有聪明的小脑瓜要问了: 如果找不到呢? 那就说明这个元 没有定值呗。 那就有更聪明的小脑瓜又要问了: 如果在寻找之前,已经有一个方程中有确定的 的系数被前面的操作调整到了数列的前面(也就是说在这个时候用不了了),到后面的时候发现没有系数为 的方程了,那这样又是什么情况呢? 实际上 这玩意我也没搞太明白 XDD 反正正确性显然( 那么,构造做法到此结束了,下面就要开始实现了。 话说 注意精度问题,判零使用 。"},{"title":"2022-10-23 总结","date":"2022-10-23T11:48:16.000Z","url":"/2022/10/23/2022-10-23-review/","tags":[["总结","/tags/%E6%80%BB%E7%BB%93/"]],"categories":[["undefined",""]],"content":"总结 2022/10/20~2022/10/23 书接上回, Codeforces 阳间比赛只打了一场。 比赛的情况还不错。AC A~D 在此总结一下做法。 Codeforces Round 829 (div.2) A. Technical Support 大概是说,要求每个 Q 之后都要有一个对应的 A。 一个 A 不能被两个 Q 所对应。 看是否能够满足这个条件。 那么可以从后往前扫,如果出现 totQ(Q 与 A 之差)< 0 的情况就会爆炸。 B. Kevin and Permutation 大概是说,有一个序列 ,要最大化 。那么观察样例 1 即可发现可以通过 来构造出 的方案。 C1. Make Nonzero Sum (easy version) 大概意思,就是有一列数 ,包含 两种值,要选出任意个区间使得这些区间 不重复不遗漏有顺序 的覆盖整个数列,使得对于每个区间的得分之和为 。定义区间 的得分为 即题面所说的 “the alternating sum of all elements of the -th segment”(即交替和——字面理解)。 考虑只有 和 两种值,那么无论如何改变 的符号,如果 ,最终加和必然是奇数,不满足所有区间得分和为 的条件。所以当 时必然无解。 那么考虑 时,如果让每一个区间和为 ,那么必然能让 (话说题面有隐晦地提到:“Note that each does not have to be equal to zero(注意每一个 可以不为 ), this property is about sum of over all segments of partition.”)。 所以只要让每一组相邻的数构成一个字串来处理, 当 时,可以让区间包括这两个数,可以使一个数的符号变过来,然后相抵消。 当 时,可以单独把这两个数分成两个区间单独相加(因为这样不改变符号),然后相抵消。 到最后就能全部抵消完。。 C2. Make Nonzero Sum (hard version) 与 C1 不同的是,这里的 可能出现 。如果采取刚才的策略, 将有可能打乱节奏,使得 与 ( 下一个不为 的数)在区间的同奇偶位上。比如说 101 的情况,按照上面的策略将会使得两个 直接相加,打乱节奏。 但是注意到 作为一个空数,他可以起到过渡作用。 首先有一个结论,非 数个数为奇数必为 -1。(理由同理) 那么现在就考虑让所有非 数个数为偶数的情况都有解。 想到可以与上一道题类似的做法,两两相抵消。但是有部分过程会稍有区别。 若 ,这种情况比较简单。对于上一道题来说,这两个数可以分别取,然后相互抵消。但是中间可能参杂 ,由于 不会影响到结果,所以可以把所有 放在一起统一抵消(或者你想单独给他们分组也行)。那么再分别取即可。 若 ,对于上一道题来说,这两个要放在同一子序列中相互抵消。但是有个问题。如果中间参杂了 ,可能会影响到互相抵消。那么可以想到一种构造方法:101 -> 1|01 这样分组分配,让最后一个 与后面的非 数相抵消,那么必然有解。再比如 1000001 -> 100000|01,前面 为正不变符号,后面 在第二个数字上,变号,那么就可以相互抵消了。 那么, D. Factorial Divisibility 如题所名,这道题分析阶乘的整除性质。 有数列 ,要判断 是否是 的因数。 那么可以想到一个很明显的结论:对于 的数可以不用考虑,因为本身就有了 的因数。 然后根据玄学的思考,其他的 可以相互合并获得 。比如说 其中的规律是 。所以通过一次次的合并可以合并到 就不用再合并了。 在合并的过程中如果出现剩余的情况,那么说明该组数据不能整除:因为剩下的 ,必然不是倍数关系。无论如何必须都要全部组合在一起才能说明是 ok 的。 以上是 Codeforces 的分析。 吐槽 Luogu S 模拟赛。 由于早于 Codeforces 1.5h,我思考了第一题并成功的想出了逆序对的做法——即要求为 ,的两颗导弹就会碰撞。 但是做到 15:00 就没有打了。T1 也没实现(否定了自己)。有些小遗憾,这次模拟赛如果打满暴力将可以冲进前 50。但是没关系, Codeforces 有进步! 这里是 T1 的部分实现代码 已经实现了记录是哪一个位置上的导弹提供的贡献。但是遗憾没有继续做下去。 先逃—— 由于疫情,停课了,三天啊 三天啊 而且中段考有可能后移导致我也得参加,这样我亏死啦"},{"title":"2022-10-20 总结","date":"2022-10-20T10:47:16.000Z","url":"/2022/10/20/2022-10-20-review/","tags":[["总结","/tags/%E6%80%BB%E7%BB%93/"]],"categories":[["undefined",""]],"content":"总结 2022/10/17~2022/10/20 书接上回, ARC 掉大分: T1 晚切,T2 思路假掉,心态崩掉——/dk 做题重心: Luogu 部分特殊算法题 + sf 的洛谷题单; 思考一点 Codeforces Problems。 比赛: 校内赛 2022/10/18: 水题复现赛。 T1 是大贪心;; T2 是大矩阵快速幂;; T3 是状压 DP; T4 —— emm—— DP;; 怎么说吧, T1 贪心稳定发挥。 T2 矩阵快速幂取模了——但是没有开 long long 乘法溢出(以后只用 #define int long long 了 /dk)pts 100 -> 30。 T3 实数输入—— 没有看题,直接读入了整数 pts 100 -> 0。 T4 没打完—— pts100 -> 0。 然后垫底。 铜锭思彤啊! 校内赛 2022/10/20: 难题汇聚赛。 T1 玄学贪心 竟然没挂; T2 神奇树上倍增—— 没调完 pts100 -> 0 (说句闲话,下午调到四点才调完 对了一下午大数据,眼睛快瞎了); T3 玄学二分—— 暴力都没打; T4 (???); 然后再次垫底。。 铜锭斯通啊! 总体表现: 还需更加细心啊 做题还要更快一点 :((( 下周有一个 Codeforces 阳间 div2,加油上分!) new"},{"title":"P4343 题解","date":"2022-10-19T11:59:15.000Z","url":"/2022/10/19/Solution-P4343/","tags":[["题解","/tags/%E9%A2%98%E8%A7%A3/"],["二分","/tags/%E4%BA%8C%E5%88%86/"]],"categories":[["undefined",""]],"content":"Problem Link 这一道二分,非常的经典( 首先,可以在 的时间内,计算出定值 对应切了多少道题目。 那么就可以二分 ,每次 check 计算出的 与原 的大小关系,并由此二分。 上下界之间只有一个等号的不同,是一样的( 坑点: 输出 -1 只用一个。 。 开 long long。 "},{"title":"2022-10-16 总结","date":"2022-10-16T11:12:03.000Z","url":"/2022/10/16/2022-10-16-review/","tags":[["总结","/tags/%E6%80%BB%E7%BB%93/"]],"categories":[["undefined",""]],"content":"停课记录: 2022/10/12~2022/10/16 做题中心: Codeforces Constructive problem *1400 - *1800 Luogu NOIP Problem + CSP Problem 比赛: 校内赛 on 2022/10/13,全员挂科。 T1 是滚动数组优化,但是空间压得很紧。 实际上这道题我花了大于 2 hour,非常不应该。 T2 找规律,但没时间做 /oh luogu 月赛 on 2022/10/16, T1,T2 过水,T3 难度爆炸,T4 不能理解其 Sub3/5。 T3 最终想出做法,离结束还有 2hour。今天晚上实践完成。 ABC 掉大分 ARC —— ? 下周主要还是向思维题进攻。~~经过严密的分析,~~CSP 常考思维题。 加油——"},{"title":"数论及莫比乌斯反演学习","date":"2022-10-15T01:12:50.000Z","url":"/2022/10/15/number-theory-and-mobius-studies/","tags":[["数学","/tags/%E6%95%B0%E5%AD%A6/"]],"categories":[["undefined",""]],"content":"话说我的数论和数学已经不够我现在用了,随便做点题都要推式子,不如先学一下有什么要学的———方便做题。 数论基础 首先必然是余数。 余数在数论中出现的频次(也许)最多了。 带余除法 ( 是常数,一般不考虑 正负,以下也不考虑) 一般取余都会带入 ,即 。 还有一种特殊余数(绝对最小余数),,即 (话说要取整吗 数论基础 - OI Wiki (oi-wiki.org) 这里没有取整) 性质 唯一性:这个 在区间内唯一。 充分性:连续取 个整数构成的剩余系是完全的。 最大公约数和最小公倍数 没什么好讲的; 辗转相除法 / 辗转相减法:欧拉定理; 高精度 gcd / lcm: 要让最终时间复杂度为 , 辗转相减法 + 二的因数优化: 高精度加减 & 高精除单精: 。 注意! 如果使用辗转相减法会使算法变为 (高精度除法为 )。 高精度送分题: P2152 [SDOI2009] SuperGCD Python Code 算数基本定理 (没听过,但显然) 引理:设 是素数,,那么 和 至少有一个成立。 定理:设正整数 ,必有: 其中 是素数,且唯一(不计次序)。 以及,合并相同的 ,得到因式分解式: 同余 表示 。 式中的 是 对模 的剩余,这个概念与余数完全一致。通过限定 的范围,相应的有 对模 的最小非负剩余、绝对最小剩余、最小正剩余。 性质(抄过来啦) From OI-Wiki 自反性:。 对称性:若 ,则 。 传递性:若 ,则 。 线性运算:若 则有: 。 。 若 , 则 。 若 ,则当 成立时,有 。 若 ,则当 成立时,有 。 若 ,则当 成立时,有 。若 能整除 及 中的一个,则 必定能整除 中的另一个。 数论函数 OI Wiki (oi-wiki.org):「数论函数指定义域为正整数的函数。数论函数也可以视作一个数列。」 积性函数 重点—— 定义 若函数(数论函数) 满足 , 都有 ,那么 为积性函数。 一定要满足 吗? 若对于 都有 ,那么 为完全积性函数。 性质 积性函数的传递性: 若 与 都为积性函数,那么以下函数也是积性函数: 应用: 设 ,(此处 是质数吗?分解质因式) 若 为积性函数,则有 。 若 为完全积性函数,则有 其中第二条与第一条区别在于乘方的位置! 例子(常用数论函数 /se \\varepsilon => 单位函数:; 提示 在狄利克雷卷积中,。 Prove it. 恒等函数: (; 常数函数:; \\sigma => 除数函数:, 是常数。 时函数记为 , 时记为 。 \\phi => 欧拉函数:。 提示 Prove it. \\mu => 莫比乌斯函数:,其中 表示 的本质不同质因子个数:加性函数 。[^ref1] 加性函数 此处加性函数指数论上的加性函数 (Additive function)。对于加性函数 ,当整数 互质时,均有 。 应与代数中的加性函数 (Additive map) 区分。 莫比乌斯反演 前置知识:数论分块、狄利克雷卷积。 狄利克雷卷积 定义 设 为数论函数。 或 (感觉后面那个式子更好看 /kk) More? 可以形象的理解为 将 分为两个数乘积,将两个数分别带入 ,乘积之和为结果。 逆 结论: 证明 性质 如果 是积性函数,则 也是积性函数; 其实这个性质在积性函数性质章节提到过—— 是在狄利克雷卷积下,它长这样:。 其他性质看这里——算法学习笔记(35): 狄利克雷卷积 - 知乎 (zhihu.com) 莫比乌斯函数 定义[^ref2] 为莫比乌斯函数,定义为 含有平方因子为的本质不同质因子个数 详细解释一下: 令 ,其中 为质因子,。上述定义表示: 时,; 对于 时: 当存在 ,使得 时,,也就是说只要某个质因子出现的次数超过一次, 就等于 ; 当任意 ,都有 时,,也就是说每个质因子都仅仅只出现过一次时,即 , 中个元素唯一时, 等于 的 次幂,此处 指的便是仅仅只出现过一次的质因子的总个数。 性质 ,。其中 Missing \\end{cases}\\varepsilon = \\begin{cases}1&n=1\\0&n\\neq 1\\\\end{cases} 。 证明:二项式定理。 反演性质 莫比乌斯变换 设 。 形式 1 若 ,则 。 莫比乌斯变换 可以看作 与 做卷积:。 证明 卷积: 已知 ,证明:。 。 , 设 : 设 : 根据莫比乌斯函数的定义, 这条式子在只有 的时候才会对式子有影响。 总共 个因数,所以 所以 。 所以 。 证毕。 形式 2 ,那么 。 例题 P2568 GCD 题目的要求: 变形: 再变: 令 ,在 时重复,所以 。 再变: 观察到中间的 可以前缀和掉, 做 的前缀和然后爆搜即可。 线性筛 phi Solution P2568 据说 LuoguP9157 逝莫反,等 WBWYX 大蛇做出来去请教一下。 Update by 2023/03/20 [^ref1]: 数论基础 - OI Wiki [^ref2]: 莫比乌斯反演 - OI Wiki [^ref3]: 浅谈积性函数的线性筛法 - 自为风月马前卒 - 博客园"},{"title":"浅谈机(J)惨(C)技巧——从入门到精通(?)","date":"2022-07-29T07:58:36.000Z","url":"/2022/07/29/qian-tan-J-C-ji-qiao-cong-ru-men-dao-jing-tong/","categories":[["undefined",""]],"content":"JC总是无聊的机房中有意思的一个瞬间。。。 比如: 这个杰作由 ZSWBWYX 完成 你认为这只是AK-IOI吗?不!注意用户名。。。也是此人的杰作。 所以,在险恶的机房里,一定要保护好自己的账号。 知己知彼方能百战百胜 ,下面我就来介绍下JC的各种方法。 windows篇 (1)线下物理攻击 要点: 抓住时机,看准时间。比如说: A去上了个厕所 。 B开始了JC,他打开了A电脑的浏览器,点开了Luogu。 他快速地在讨论区里打了“I AK IOI”的字样。 此时,C帮助B锁住了门。 等到B完成他的工作时,A刚好回来,就被C挡在了门外。 C放A进来,B已经退出了A的账号。(这使A登录删除的速度减缓不少) 完美! 这就是上图的来源。B就是ZSWBWYX,此人今天被别人JC 解决方案: 注意上厕所的时机,在离开电脑时记得锁定账户。 还要搞好同学关系 (2)线上各路工具 这里举几个例子。(笑) [1] JC Tools 通过远程服务器端响应,实现类似Telnet功能。 要点: 要提前给A开好电脑,装上JC Tools 服务器端。 记得不要把自己的表情显示出来!(我就被识破过。。。) [2] 直接用Telnet 这里不再多说。 (3)自己动手,丰衣足食 通过自己做的钩子,识别键盘按键,通过记录键盘来获取密码 要点: 技术含量要求高,推荐易语言 (非广告) 小心提防各种程序Bug,以防对方发现被JC。 要提前做好(2)的操作,给对方装上记录装置。 小心走火入魔,忘记学OI! 例子: 。。。算了伤心往事不提了 Windows篇总结 只要注意好线下JC,加上小心警惕,就足够提防了! Linux篇 Linux主要用于线下Linux环境比赛。 不过这里仅做技术汇报,建议不要用在大型比赛,小心被查。 对于公示期间收到的举报,CCF NOI科学委员会调查后判定选手HN-0117(Karry5307)的2题分数为0,省选结果相应变化。 (1)官方工具攻击 说起远程连接,肯定是ssh啦! 不过再说一遍:警告:请勿在正式比赛中使用!您将会被禁赛三年的风险。 首先你要懂得Linux-Bash基础指令。 最主要指令: ssh [email protected] aaa☞用户名。 登录后,你需要熟练使用vim、cat等命令行工具,对其代码进行操作。 比如 1、用cat显示别人的代码然后自己改改,A掉 2、删除别人的代码,用心险恶 3、帮别人复制一个板子进去,赛后举报 4、帮别人改动一下,于是MLE/TLE/CE/RE 再说一遍:警告:任意一项都会让您面临被禁赛三年的风险。 还有scp指令,与ssh类似,只不过不需要登录命令行。请读者自行查资料。 对于那些利用SSHJC的人,你可以这样做 (1)若你发现了确切证据,保留日志,赛后举报。 日志在这里:~/.bash_history (2)若怕发生被JC事件却没被发现,你可以:pkill sshd 或 拔网线 补:sshd就是ssh的服务端 (3)反其道而行之 算了,会面临被举报风险。(逃) 这里附上大佬Karry5307的JC经历 请勿模仿!"},{"title":"P1687 机器人小Q 题解","date":"2022-07-29T07:58:28.000Z","url":"/2022/07/29/solution-p1687/","categories":[["undefined",""]],"content":"我看这题似乎没有将状态转移方程讲清楚的题解啊,所以我来了 入题。 看到这题,我立马想到贪心。 对题意,我的错误的理解为:对于任意一个能量菜单上的能量值都可以在任意时间充电。这样,就可以直接排序选前个最小值进行充电。 然后,我看到了此题的颜色:普及+/提高 这题不简单! 于是,我就看到了讨论中的: 贪心60分求助 算法疑问 是题目问题还是我的问题 哦原来是 按一定顺序 给出了 个单位的能量值,使用也得 按一定顺序 。也就是说,用了第 个后,第 个之前的就不能再用了。 好了,排序不能用了,决策题只能考虑动态规划了。 于是设 表示在第 个之前使用了 种能量值时最少用的天数。 比如说对于样例, 表示第三个能量值之前的三种能量值1,119,119中要选择两个能量值并充电给小Q。 考虑 和 之间关系。 若 i==j 若 ,也就是说前 个一定要全部选,那么第 项也一定要选。那么就考虑选择第 个: 看起来那么长,其实就是将一个if嵌在其中。 首先, 指前一个选择了 项的状态,到此状态是刚好选择 项。 而后面的一个三元运算,则指是否需要重新的一天来充电——用题目的话来说就是充电量超过了119,则要用另一天来充电。否则小Q就要原地爆炸 注: 数组保存着在第 , 状态时那一天已经用了多少能量; 若 i>j 再考虑 。这表示在前 种能量值中只用选择 个,而并不用全部选完。这就又分两种情况: (1)不选第 种能量。 (2)选第 种能量。 对于(2),在 时我们已经讨论过了,那么只需要Ctrl-C+V就好了。 对于(1),直接 就得了,没啥要考虑的。 只要对比(1)和(2)的大小就OK了。 依照上面的思路,我们可以写出这个简单的代码。 (不要着急复制粘贴AC这道题啊,因为下面的代码只有30分) 好,为什么30分呢?等等, 的情况没考虑完整!若选择和不选择的天数相同呢? 先停一下,看看 的含义。它表示在第 个之前使用了 种能量值时最少用的天数(的向下取整)。对啊!这使当前这一天的使用的能量没有发挥作用啊! 还是举个粒子吧。 现在已经使用了这样的能量组合: 118 1 50 到第三天时,用了1天并还剩下50的能量。剩下的50能量便是主要要对比的对象了。 那么,天数相同时,最后一天所用的能量肯定越少要好啊!所以,在天数相同的情况下,就选择最后一天使用能量较少得那一种方案。 于是代码变成了这样: 完结。 等等?为什么没有“You can’t do it.”都可以的? 哈哈哈,这说明了一些显而易见的事实。 既然想到了那么就说一说怎么判断吧。如何凑出不可能充k种电的情况呢? 只有一种情况,就是没有足够的方式充电。 那么输入就可以改成这样: 正式完结。 有不懂得问题,问我哈 有错误请指出,方便我改进自身qwq"},{"title":"P1172 安全逃离 题解","date":"2022-07-29T07:58:21.000Z","url":"/2022/07/29/solution-p1172/","categories":[["undefined",""]],"content":"数据点望 Luogu 能完善下 好,讲解正式开始。 拿到正确题目后,能想到的就是模拟、暴力。虽然这是一道普及的题目,我们也要将代码优化得更加 短小精干。 我们要模拟啥呢? 1、首先,对于每一个牛,我们都要检查他能不能离开。 对于每一个牛,它上方格子或右方格子中,一定要有一条完全没有其他牛。 就说上文的样例。 号上方有 号,向上走行不通。同时有房还有 号,向右走,也行不通。所以这头牛就不能安全逃出。 同样我们可以看出,要让整个图安全,只要去掉 ,, 的任意一个,就可以解决纠纷了。 2、其次,如果不是安全的图,我们要尝试去掉每一个牛,来尝试能否使图变得安全。 这里,我似乎想到一个优化的方法,就是将发生冲突的牛记录下来,在去牛的时候只检查这些就够了。 可惜数据太小,也没太大用,这里只起抛砖引玉的效果。 用上面这两条足以通过此题。 上代码! 时间复杂度: 有啥问题?留言问我。 jr 的第二篇题解 awa cnt = 2"},{"title":"P7774 KUTEVI 题解","date":"2022-07-29T07:58:13.000Z","url":"/2022/07/29/solution-p7774/","categories":[["undefined",""]],"content":"写这篇题解花了我很多不少时间,希望能过 awa 题意: 有 个数,这 个数能否由另外 个数通过加减运算获得。 对于每一次加减的操作,结果不能小于 (角度不能小于 ); 对于大于等于 的结果,对 取模。(大于 的角会转一圈后继续转) 能则输出 YES ,不能则输出 NO 。 思路: (背包)、搜索都可以。dp 太难想 这里我只讲搜索。 对于每一个状态,只有加和减两种状态。所以只需要对每一个状态枚举每一个数的加或减。 记录已经过状态,枚举中遇到了要获得的数,就表明可以实现。枚举结束后还没有遇到,则不能实现。 实现: 对于状态 , 拓展 且 且未被拓展过。 上代码! 完结。 对于可以不枚举 的证明: 对于任意正整数 ,,,,证明: 。 指某一状态。意思就是,只用加 次 就可以枚举到 。 原式可转化为: , 为任意正整数。 化简,得:。 所以,只需证明 恒为 倍数。 若 为 倍数,得证; 若 不为 倍数, 则若使 为 倍数, 即可。 又有 ,则 。 则 在满足 的条件下满足 ,所以无论 取多少都能满足 为 倍数。得证。 综上,。 第一次自己写 OI 证明题,有不对或不完善的地方请指出,谢谢qaq; 被打回x4 – 求过!"},{"title":"P7767 DNA 题解","date":"2022-07-29T07:58:06.000Z","url":"/2022/07/29/solution-p7767/","categories":[["undefined",""]],"content":"虽然我似乎解释明了贪心是可行的,但是我还是有些不爽 dp 做更直观吧 Solution 入手这道题,看了看,就直接奔去写贪心。 至于如何贪心? 题目大意:对于每一个操作有两种操作选择,使终串全为 。 对于这道题,贪心只考虑局部最优解,不能影响到其他位置 于是,就有两种情况要讨论: 单独的 B 对于单独出现的 , 执行方法 1 需要 1 步,即直接修改(操作 1)。并且不会对字符串造成其他影响。 执行方法 2 需要 2 步,才能使字符串不会出现变化。 比如说: 在位置3执行操作2, (操作 2) 再在位置2执行操作2, (操作 2) 显然,当出现单独的 时,执行方法 1 改变单个字符更优。 连续的一串 B 对于出现一串的 执行方法 1 需要执行 步, 为全 子串。 执行方法 2 需要执行 2 步,与 “单独的 B”中考虑一样。 由于 ,所以,在出现连续的 串时,执行方法 2 更优于方法 1。 综上,需要不影响其他步骤,从右往左扫; 单独的 就直接修改; 连续的 就通过方法 2 改变(其实第二次操作没必要进行,因为执行结束后会继续往前扫,自然会继续改变)。 上代码! 还有更好的贪心思路要告诉我啊 qaq。"},{"title":"P7755 POREDAK 题解","date":"2022-07-29T07:57:58.000Z","url":"/2022/07/29/solution-p7755/","categories":[["undefined",""]],"content":"其实这道题渟水的 Solution 题意简化: 在一堆字符串中间,找到一些两两相对位置正确的字符串的个数。 其实,我们可以给这些字符串标号。 就比如说,按样例 1, 对正确序列标号为 。 就可以将给出的序列变成 。 于是就只用寻找正确的编号大小关系即可。 可以在上面序列中找到两组: 和 。于是答案就是 。 最后变成了找逆序对正序对的问题。 实现: 编号,再用 枚举就可以啦~ 虽然可以用归并排序解逆序对,但时间复杂度不需要。 qaq"},{"title":"CSP初赛考点汇总","date":"2022-07-29T07:57:51.000Z","url":"/2022/07/29/CSP-ChuSai-KaoDian/","categories":[["undefined",""]],"content":"非广告:csdn的博客 东西太多,luogu列表不太友好(没有有标题链接,不便寻找) qwq 为SCP初赛选手(我)收集的各种定理qwq 更新: 1、为了初赛都能用,不限于定理了 2、主旨为在短时间内复习各算法,备初赛 3、请确定你学习(学懂了)了 的基础知识。 可能会一直更新下去qwq 最新:2021/9/11 10:03 1、主定理 在求某一分治(递推?)算法时间复杂度中适用。 规模为 的问题通过分治,得到 个规模为 的问题,每次递归带来的额外计算为 即 。 求执行 的时间复杂度。 定理: 若 , 若 , 若 , 套就完事儿了 证明请bdfs 2、等比数列 指一个数列所有数有公共比。 比如:,,,, 此时公比为 。 等比数列通项公式为 即为数列首项, 就是公比。 比如说,求上面那个等比数列的第五个数。 求得 。 根据通项公式,我们可以轻松得到前 项的求和公式。 还是比如:求上面那个数列的前五项之和。 求得 。 至于推导嘛,它来了! 2.1 等比数列求和公式推导 首先,先将通项公式列出来。 提 。 添一个 。 乘开, 消掉一大堆, 此时要求 且 最终得到 应用嘛,其实很广的。 2.2 应用:h层满k叉树求节点个数 第 层 个; 第 层 个; 第 层 个; 第 层 个; … 第 层 个。 这不就等比数列吗。上求和公式! 注意! 这里其实有 层,所以为什么是 。 题目链接:Noip2018提高 - 第四题 3、贪心 贪心算法(英语:greedy algorithm),是用计算机来模拟一个 “贪心”的人 做出决策的过程。这个人十分贪婪, 每一步行动总是按某种指标选取最优的操作。 而且他目光短浅,总是只看眼前,并不考虑以后可能造成的影响。 可想而知,并不是所有的时候贪心法都能获得最优解,所以一般使用贪心法的时候,都要确保自己能证明其正确性。 ——Copy by OI-WIKI 从中可以看出,贪心所讲究的,是思维的 贪度和正确,二者一样重要。 (贪度,即为贪心的层次,越贪心,贪度越高 我瞎掰扯的, 理解就好) 首先,贪度的提高并不是一次思考就能完成的。 就好比时间复杂度需要一步步优化。 贪心的主要内容,证明等皆在OI-Wiki中有讲述,可以到oi-wiki找到详细的讲述。 4、二分 二分,可以理解为分成两半。在二分基础应用中,二分是用来在一 有序 数列中寻找数的快速方法。 注:必须有序! 比如, 我需要在 中寻找第一个比 大于(等于)的数。 比如说 ,则找到的数下标为 。 4.1 基本实现 1、令 2、又令 3、对于 , 若 ,因为整体有序,所以 一定在 左边(或它本身)。 这里等于号放在这里,是因为即使等于了,第一个说不定还在前面。 若 ,同理, 一定在 右边。 持续进行步骤二和步骤三,当 时,就找到了。 这就是最基本的实现。 实现代码:(arr为有序序列) 4.2 进阶实现 首先,二分一般实现于最值最化。 简化最值最化的要求: 1、答案在一个固定区间内; 2、查找不容易,判断容易(比如说找数); 3、可行解对于区间满足一定的单调性。 如果一个数组中的左侧或者右侧都满足某一种条件,而另一侧都不满足这种条件,也可以看作是一种有序(如果把满足条件看做 ,不满足看做 ,至少对于这个条件的这一维度是有序的) 这就是指某一个数组的左边 或 右边都满足某一条件,即单调性 可以理解为上上上上面的例子中, V[3] 左边都满足小于 3 这个条件。 4.3 实际应用 见二分答案 5、三分(待填坑) 6、哈希 对于初赛来说,只需理解哈希函数以及哈希碰撞即可。 哈希列表的概念是差不多的 哈希函数 & 哈希碰撞 简单来说,就是将某一难处理的数值、字符串通过某一处理函数处理成简单的数字。 看例子就可以学懂了: 设哈希函数为:, 则 的哈希值为 , 的哈希值也为 。 此时 和 的哈希值相同,有同样的哈希值保存,会导致碰撞,称为哈希碰撞 7、KMP(待填坑) 放链接。 8、最小生成树(待填坑) 放链接。 9、最短路 这里只讲 Floyd,Dijkstra,SPFA 提醒: 除了 Floyd 算法以外,都建议使用邻接表。邻接矩阵时间复杂度为O(n^2),等同于没优化 9.1 Floyd 时间复杂度: 评价:最简单的最短路算法,最高的时间复杂度,最划算的多源最短路。 注意事项:中间节点k一定要放在最外层,至于后果,需按数据手推( 思路:一一枚举每两个点的最短路。 样例代码: 9.2 Dijkstra 时间复杂度: 在稀疏图中,使用二叉堆实现的 Dijkstra 法的 即 较 Bellman-Ford (SPFA) 算法的 具有较大的效率优势; 而在稠密图中,这时候使用暴力做法 较二叉堆实现更优。 但一般只使用优先队列法 ,代码最清晰简短,但时间复杂度在稀疏图上比二叉堆略差。 评价:十分经典的单源最短路,在单源最短路中时间复杂度最强,但不能处理负环。各种方法形成不同的时间复杂度,容易考到。 注意事项:不能处理负环! 思路:推荐这篇博客 样例代码: 对于上面 vector<edge> e[maxn],是邻接表的一种实现,内存消耗是动态的,并且最方便,但时间复杂度 可能 偏高。 9.3 SPFA 时间复杂度:随机数据中表现优秀,但平均时间复杂度为 。 评价:最好理解的最短路,最容易Cu卡爆的最短路。 注意事项:能处理负环。 思路:有点类似BFS,是BF的队列优化版本。 样例代码: -by oi-wiki 10、位运算 这位大佬的博客 写的不好,勿喷"},{"title":"Radioactive 题解","date":"2022-07-29T07:57:43.000Z","url":"/2022/07/29/radioactive-ti-jie/","categories":[["undefined",""]],"content":"这道题还是很水的,做了三天才做出来 Solution 一看区间操作,就是线段树。 不过虽然说着简单,但是细节有很多,请注意这里讲到的每一个细节。 解题思路 观察下放操作,先是升序,再是降序。 若是直接下放,会出现很多复杂的情况,比如说,原来的序列被切分成 的情况。这样就要处理很多特殊情况。 经验告诉我们, 操作可以分解为一次上升,一次点修改,一次下降。 即: 变为 与 和剩下的 的操作。 单独操作,每一个下方操作都是单调的,没有特殊情况。 对于 ,我们保存两个 ,分别用来记录下放的上升和下降。 每一次分配 直接使用等差数列求和公式求和即可。最坏时间复杂度为 。 这里之所以说是 ,是因为每一次下放的操作都会遍历之前的所有 操作,肯定可以卡到 。况且空间复杂度为 。绝对需要优化。 优化 注意到就是 的下放导致时空爆掉,所以我们重点攻克 的下放和记录操作。 在一节数学课前,我找到了灵感: 等差数列有个不知道是不是定理的真命题,即两组长度相同的等差数列,每个数一一对应相加时,得到的等差数列,首项为两组等差数列的首项之和,末项也是末项之和,同样的,公差也是两公差之和。 至于证明,很简单嘛( 然后,我们就发现,每次 记录的长度都是固定的,即 。 所以,我们只需要记录并累加首项,末项和公差即可。 时间复杂度降为 (可能带点大系数,我不想优化了);空间复杂度降为 。 细节 1 和 有可能为负数,稍微加个数就好了 2 下放的时候一定要按照区间划分好的 和 来划分,否则有可能划错。 3 在下放时,只需要保留在 和 区间内的修改就好了。 第一行两个整数 ,表示你负责的区间在 ,共有 组事件发生。 不会有人没看到吧 4 就没啥了 ,都是我粗心错的小错误 Code 完结撒花qwq"},{"title":"UVA144 Student Grants 题解","date":"2022-07-29T07:57:35.000Z","url":"/2022/07/29/solution-uva144/","categories":[["undefined",""]],"content":"Long time no write, Please pass it over!!! Solution 最近都在刷水题,就看到了这道水题 模拟题,只要读懂都会做qwq 题意即为:一堆学生去取钱,取的钱数按照顺序,成递增的序列,为 元。 取第 次钱的学生将会取到 元。 若是某一个同学取完了 元,则他就会退出取钱的队伍,就是说,取完钱了。 要是取多了前,即取得钱数大于 元,则多出 元的钱给下一个排队的同学,并且下一个同学回到队尾。 举个栗子, 有 个同学,分别取了: 元钱。此时,最前面的同学可以取 元钱,那么钱数就会变为 第一个同学取完了所有钱,将多出来的钱给后面的同学,并离开队伍。 队列就变成了 下一个同学本来要回到队列尾端,但是由于 ,所以他也可以离开队列了。 就变成了 此时,所有同学都可以离开队伍,结束所有过程 所以,就可以枚举每一个同学取的钱数,加上队列模拟,就可以k掉了。 code "},{"title":"P7541 DOBRA 题解","date":"2022-07-29T07:57:24.000Z","url":"/2022/07/29/solution-p7541/","categories":[["undefined",""]],"content":"solution 题意简化 一个字符串,将所有的 _ 替换成大写字母,使结果字符串符合要求: 1、不包含三个连续 元音 或 辅音 字母; 2、字符串中至少有一个 L 。 求最终字符串可能的个数。 看到这道题,即想到了万能的算法——搜索。 从下标 开始,枚举每一个字母。 由于每次枚举的字母与后面的枚举无关,所以这样搜索不会出现重复的终串。 在枚举结束时使用 check 检测是不是合法终串,如果是就是一种情况。 可惜,只会拿到可怜的 的分数。 先来算算时间复杂度吧。 对于每次操作,都有每个 _ 需要枚举 次,同时最多有 位,所以枚举次数最少 次方,超时是稳稳的。 所以如何减少时间复杂度呢? 我们可以发现,这道题实际上**辅音字母之间并没有区别。**同理,对于元音字母也是如此。 所以,可以每次只枚举两次,对于辅音字母的结果乘 ;元音字母的结果乘 。 还有一点要注意,由于 L 会影响结果,所以需要特殊考虑。 总共 次,枚举次数降为 ,AC 稳稳的。 AC Code: 从 9 s 降到 30ms,质的提升啊! 哦。"},{"title":"P7542 MALI","date":"2022-07-29T07:57:17.000Z","url":"/2022/07/29/solution-p7542/","categories":[["undefined",""]],"content":"又双叒叕水了一篇题解… 题目简述 对于两个序列 A,序列 B,长度一致; 共 次操作, 每次操作都会向这两个序列增加数字。 在每次操作后,要求对每个序列中的每个数字配对,要让配对数之和的最大值最小。 Solution 贪心。 对每时每刻的序列排序, 中从小到大与 中从大到小配对。 证明: 对于序列中最小的 ,序列最大的, 若将 替换成 且 ,此时必有 ,不必原计划更优; 若将 替换成 ,且 ,则必有 需要与 配对。所以必有更大值 ,也不必原计划更优。 所以,每次选择最小和最大的配对可以得到最优解。 可惜直接排序时间复杂度不够。 时间复杂度为 ,,超时。 优化。 1、桶优化 发现 ,所以考虑直接桶排。 时间复杂度降为 。 2、连续配对优化 发现当 出现多次时,会直接配出 组一样的配对。 所以对于桶中 ,每次配对时,对应减少 即可。 最坏时间复杂度为 ,不会超时。 AC Code qwq"},{"title":"玄学优化之——快读","date":"2022-07-29T07:57:09.000Z","url":"/2022/07/29/xuan-xue-you-hua-zhi-kuai-du/","categories":[["undefined",""]],"content":"对于基础读入读出,有基本的快读: 根据这个基本快读,结合不定参数,可以得到加强版 reads 和 writes。 reads 支持多参数; writes 支持多参数,且输出格式为 \"%d %d ... %d \\n\" 注: 请注意格式,以及不要用错了。"},{"title":"抄题解 题解","date":"2022-07-29T07:57:02.000Z","url":"/2022/07/29/chao-ti-xie-ti-xie/","categories":[["undefined",""]],"content":"Solution 观察题面,由数据范围可知这道题的复杂度为 O(n log n) 作法为贪心。 如何贪心呢? 在与 @ryanright 的交锋往中,认识到一点他的做题技巧: 1、能做的题先做; 2、做不了的选择最高收益的做。 所以,就能通过优先队列写出下面的代码: 不过这是否正确呢? 证明: 1、优先做能做的(能力值范围内的)是必须的。 能做的,不会降低能力(注意 ),且之后的题目会有更高的收益。 2、做不了能做的,就做收益最高的,也是必须的。 没有能做的,就代表不一定会增加能力。当增加为正时,相对于其他题目,会让后面有更多的收益;增加为负时,相对于其他题目,会让后面做的题扣的能力更少。 /kk"},{"title":"Good 博客收集栏","date":"2022-07-29T07:56:53.000Z","url":"/2022/07/29/Good-bo-ke-shou-ji-lan/","categories":[["undefined",""]],"content":"如题。 图论 并查集 算法学习笔记(1) : 并查集 “按秩合并”并未看完 "},{"title":"NOIP2021 退役记","date":"2022-07-29T07:56:46.000Z","url":"/2022/07/29/noip2021-tui-yi-ji/","categories":[["undefined",""]],"content":"Day -114514 考完 csp,心态比较炸裂,有点恢复不起来,然后听说 noip 有机会去玩,心态好了一些。于是就等了等,最后我提高三等奖也能蹭个名额,就准备足了去玩一玩。 于是…就十分离谱的去参加了 noip2021。 Day 1 早晨 6:30 就起来了,困得要命,晚上又没睡好,就有点困;7 点去了学校,结果他们都比我早。 坐车去了 zsjz,在等待的时候面基了其他一些小学同学奆老,来虐菜,其中一个据说最后两百多分。 就草草的开始了比赛。比赛的键盘空格有坑,有时候按下去敲不出空格来,然后监考老师态度很好,不给换之类的。幸好后来习惯了。 刚开始,打了个快读,看第一题,开始的想法是打暴力,再看一遍,诶,线性筛经典题目,直接上正解。 大约花了 10 分钟,搞定第一题; 第二题,打暴力; 第三题,想了想,打暴力; 第四题,花了两个小时打暴力 ,结果没分。 最后大约检查了 30 分钟,硬是查出了一堆问题,顺便写了个作文。 前面两排中看到有人在颓 dino,似乎已经打到了几千分了,瞬间起了 Orz 之心。 于是,noip就这么结束了。 不想写了/qq"},{"title":"P7964 Kaučuk 题解","date":"2022-07-29T07:56:39.000Z","url":"/2022/07/29/solution-p7964/","categories":[["undefined",""]],"content":"好久没有写题解了,社贡掉的太低了,就来写入门题解了 Solution 观察题面,大模拟。 模拟思路,是维护三个变量 ,分别代表一级标题序号,二级标题序号以及三级标题序号。 代表到上一个父标题没有同级标题。 设当前的状态为标题的级别, 比如 这样,在前三个时三个状态都为 ,第四个标题时状态为 ,第五个标题时状态为 。 在插入新标题时, 若当前状态对应的变量为 ,那么就要插入新的标题。这时,让这个状态变量设置为 ,表示当前级标题序号为 。 若当前状态对应的变量不为 ,那么说明前面有相同级别的标题,需要在后面接一个新序号的标题,那么这个变量就自增 。 操作完成后,直接输出三个序号即可。 举个例子: 执行第四步时,需要在原来基础上增加一层标题,那么就要令 等于 。 执行第五步时,层数掉回了一级,那么在他之上就没有二级和三级标题了,就让 和 都设为 , 自增 。 Code "},{"title":"UVA10966 3KP-BASH Project Sol.","date":"2022-07-29T07:56:31.000Z","url":"/2022/07/29/solution-uva10966/","categories":[["undefined",""]],"content":"啊…太坑了 我放弃了 为了让后人不再掉坑,我在这里将刘汝佳在《算法竞赛入门经典——训练指南》中的翻译打出来。 (为了加强严密性,题目文字根据官方数据进行了增删) 你的任务是为一个假想的 3KP 操作系统编写一个简单的 Bash 模拟器。 由于操作系统本身还没有写完,你暂时需要在模拟器的内存中虚拟出一个文件系统,而不是和真是的文件系统交互。 下面介绍 3KP 操作系统中的文件系统。 文件(file)是数据存储的最小单位。文件名有英文字母(大小写敏感)、数字和点(.)组成,但不能包含两个连续的点,且用户创建的文件名不能是单个的点字符(即 . )。 文件名长度不能超过 ,文件大小不能超过 。一个文件可能具有 directory 属性和 hidden 属性。 目录(directory) 是一个大小为 ,具有 directory 属性的文件,里面可以保存任意数量的文件(无论属性)。 空文件系统只有一个文件,叫做“根目录”。在任意时刻,有一个称为“当前目录”的目录。Bash 启动时,当前目录就是根目录。 指令中引用文件的时候,可以使用绝对路径和相对路径。 绝对路径以字符“/”开头,如“/home/acm/uva”;相对路径不以字符“/”,当前目录和父目录分别用“.”和“…”表示。 如当前目录为“/home/acm/uva”,那么“…/…/…/home/…”就是根目录。 这里展示访问的过程: 你的 Bash 模拟器需要支持 个命令,具体如下: (没有 [] 标志的参数为必选参数) (又:Markdown 表格不支持回车,只能直接打了 qwq) 1. cd path 改变当前目录。path 可以是相对路径,也可以是绝对路径。 如果目录不存在或名字不合法,输出 path not found 2. touch filename [-size] [-h] 修改文件。 filename 应由两部分组成,前一部分是目录(为空就是当前目录),后一部分为文件名。 比如: 都是合法的。 其中的文件名应当是合法的文件名,否则输出 bad usage(见后)。其中的目录应当是当前文件系统中存在的目录,否则输出 path not found。 在正常情况下,同名文件(如果有的话),应当先被删除,然后新建文件。 文件的大小由 -size 参数决定(若没有参数 -size 默认为 0),参数 -h 表示创建隐藏文件。用户不会制定多个 -size 参数。 如果存在一个同名的目录,输出 a directory with the same name exists。 3. mkdir path [-h] 与 touch 类似。 创建目录。 path 应由两部分组成,前一部分是目录(为空就是当前目录),后一部分为新建目录名。 其中要新建的目录名应当是合法的目录名,否则输出 bad usage。其中的目录应当是当前文件系统中存在的目录,否则输出 path not found。 参数 -h 表示创建隐藏目录。 如果存在同名目录或文件,输出 file or directory with the same name exists。 4. find filename [-r] [-h] 查找目录或文件。 filename 应由两部分组成,前一部分是目录(为空就是当前目录),后一部分表示要查找的文件名(注意,这里表示在前一部分目录中寻找后一部分中的文件)。 前一部分目录应当是当前文件系统中存在的目录,否则输出 path not found。 -r 参数表示要查找的目录下的所有子目录都要查找。默认情况下,find 命令不会显示隐藏文件,(但是在有 -r 参数的情况下是会搜索隐藏子目录的),如果指定了 -h 参数,则会显示所有搜索到的隐藏文件。 如果没有找到需要输出的文件,则输出 file not found。否则对于找到的每个文件,输出单独的一行,按顺序会这样输出: 其中如果结果是隐藏或目录文件,则依次输出 hidden 和 dir。中间要有空格隔开。 结果应当按每个文件的绝对路径的字典序从小到大排序。 5. ls [path] [-h] [-r] [-s] [-S] [-f] [-d] 展示目录中文件。 总共 个可选参数,没有必选参数。 ls 展示方式与 find 相同。 path 指定展示的目录。若没有 path 选项,则制定当前目录为要展示的目录。 -h,-r 与 find 指令相同。 -s,-S 表示输出的顺序,-s 表示按照文件大小从小到大排序,-S 表示按照文件大小从大到小排序。如果没有制定其中任意一个参数,那么排序方式与 find 一样。又如果,两文件大小相同,那么也按照 find 的比较方式来排序。 比如说,如果没有指定 -s 和 -S 参数的结果是这样的: 那么指定了 -s 的参数排序如下: 指定了 -S 的参数排序如下: -f 表示只显示没有 directory 属性的文件; -d 表示只显示有 directory 属性的文件。 注意:两个参数可以同时出现。 6. pwd 输出当前目录的绝对路径。 7. exit 退出 Bash。 在本题中,表示初始化 Bash。 8. grep “string” 筛出输入字符串中含有 string 串的行。 在本题中,grep 只能通过管道调用。 何为管道? 简单理解,就是将管道分隔符(|)前面的程序输出结果输入到后面的程序中。 比如说,假设 ls 命令当前是能够输出这些内容的: 如果我的命令是这样子的:ls | grep \"5\" 那么,grep 会筛取前面输入的字符串,并筛去不含 “5” 的行。 加上 grep 结果如下: 注意:管道可以叠加使用,只检查 string(不带有双引号)。 对于上面的结果,我们其实可以再添加一层 grep。 命令变为 ls | grep \"5\" | grep \" 5\"(注意后面的 grep 中有空格),那么输出就变成了: 由于在前一次 grep 结果中,第二行找不到 \" 5\",所以,第二行被筛去了。 命令行中每一行包含一条或多条命令,用管道分隔符隔开(管道分隔符前后不一定有空格)。 第一条命令必须是除了 grep 之外的上述命令之一,而剩下的命令必须是 grep。 如果违反上述(上两行)中的规定,应输出 bad usage,并且不执行任何之后的命令(即之后的 grep)。 比如说: 输入保证满足以下条件: 每个命令的必选参数(如果有的话)都是第一个参数,可选参数在必选参数之后,但可能以任意顺序出现。 命令和参数,参数和参数之间保证有一个或多个空格。 用户不会忽略必选参数,不会使用非法参数,也不会在除了 grep 外的其他命令中使用引号。 如果第一条命令是 touch 或者 mkdir,且命令返回 bad usage,则不执行后面的命令(即 grep)。 模拟思路: 拆分命令和参数。 用一棵树来表示文件系统。 注意以格式化输出。 这里贴心的附上刘汝佳的代码 我的代码: "},{"title":"CF1260A Heating","date":"2022-07-29T07:56:23.000Z","url":"/2022/07/29/solution-cf1260a/","categories":[["undefined",""]],"content":"这是一道结论贪心题。结论简单,但是推倒的过程可能不止 入门。(个人感觉,可能有普及) 先说结论,对于每个 都有答案 但是如何得到呢? 这就要有严谨的证明。 首先,看题目,将题面抽象出来,就是这样的: Missing or unrecognized delimiter for \\Big ans=\\min\\Big{\\sum_{i=1}^{c}k_i^2,\\sum_{i=1}^{c} k_i\\geq sum\\ \\texttt{and}\\ k\\in Z\\Big} 形象化理解,就是把一个数分成 份,使分出来的数字的平方和最小。 于是,就按生活经验来判断,分成 份且平均的分配会有着更好的 。 首先,对同一个分的份数 ,证明,越平均的分配结果越小。 就等价于证: 证明过程如下: 先左右两边相减。 $$ \\frac{a^2}{k}-\\sum^{k}{i=1}a_i^2 \\frac{(\\sum{i=1}^k a_i)^2}{k}- \\sum_{i=1}^k a_i^2 \\frac{\\sum_{i=1}^k a_i^2+\\sum_{i=1}^{k-1}\\sum^{k}{j=i+1}2a_ia_j}{k}-\\sum{i=1}^k a_i^2 \\frac{-(k-1)\\sum_{i=1}^k a^2_i+\\sum_{i=1}^{k-1}\\sum^{k}{j=i+1}2a_ia_j}{k} $$ 重点! $$ \\frac{-\\sum{i=1}^{k-1}\\sum^{k}{j=i+1}(a_i-a_j)^2}{k} \\because -\\sum{i=1}^{k-1}\\sum^{k}{j=i+1}(a_i-a_j)^2\\leq 0, k>0 \\therefore \\frac{-\\sum{i=1}^{k-1}\\sum^{k}{j=i+1}(a_i-a_j)^2}{k}\\leq 0 \\therefore k(\\frac{a}{k})^2\\leq \\sum{i=1}^k a_i^2 $$ 这就证明了在相同 之下,平均分配要比不平均优。 还有, 越大,结果越优。 即证明: 证明是显然的。 所以分配越多越好。 所以, 份全部分配,每一份越平均越好。 可能有读者注意到,前面的命题中,要求 。在本题中,这是不一定的。用鸽巢原理,将剩余的,也平均分到每一份当中。 所以, 的正确性就证明出来了。 上代码: "},{"title":"CF347A Difference Row","date":"2022-07-29T07:56:14.000Z","url":"/2022/07/29/solution-cf347a/","categories":[["undefined",""]],"content":"观察原序列, 可以化简得到 所以,抵消中间的项,可以得到最终式子为 要让这个最大,直接让 即可。 又要求按照字典序排列,那么排一遍序,最后交换首尾两个数字,就 ok 了。 "},{"title":"CF412A","date":"2022-07-29T07:56:06.000Z","url":"/2022/07/29/solution-cf412a/","categories":[["undefined",""]],"content":"很清晰的思路,就是向左再向右。 绘字符的时间是固定的,想要减少只能减少中间的搬梯子浪费的时间。 向左,为了一次性解决左边的字符,如果不是一直向左,那么中途必定向右,而左边还有未处理的字符,说明还需要返回,这时就浪费了两个小时;向右同理。所以,处理左右两边的字符,要么不处理,要么就直接处理完。 那么,先向左还是先向右呢? 观察发现,先向左,那么中途浪费的时间就是左边节点数的两倍;先向右是右边节点数的两倍。自然是优先选择节点数少的了! 那么,分类讨论,并整理模拟思路,就打出这样的代码: "},{"title":"Easy 的题 题解","date":"2022-07-29T07:55:59.000Z","url":"/2022/07/29/easy-problem-solution/","categories":[["undefined",""]],"content":"如题目名字,这是一道简单的题。观察式子, Missing or unrecognized delimiter for \\Big \\Big{\\sum_{k_i\\geq 0,(\\sum_{i=1}^n k_i)=k} \\Big[\\frac{k!}{\\prod_{i=1}^n(k_i!)}\\cdot\\prod_{i=1}^n(i!)^{k_i}\\Big]\\Big} \\bmod p 就是 Missing or unrecognized delimiter for \\Big \\Big{\\sum_{k_i\\geq 0,(\\sum_{i=1}^n k_i)=k} \\Big[\\binom{k}{k_1,k_2,\\cdots,k_n}\\cdot\\prod_{i=1}^n(i!)^{k_i}\\Big]\\Big} \\bmod p 利用多项式定理可以化简得, 再把 搞进去,就成了这样: 这时候,首先,时间复杂度可以变为 ,此时可以拿到 分。加上快速幂可以变为 。 还有阶乘的递推关系可以降到 。 现在解决如何处理 。由于 ,必须要优化。观察到当 时,对式子的贡献为 。所以,可以化为 此时最坏时间复杂度为 。又因为 ,可以咔过。 另外,因为只保证 ,所以模数 可能 ,long long 会爆掉,只能用 __int128 或高精( 所以,Solution: "},{"title":"键盘按键对应 ASCII 码记录","date":"2022-07-29T07:55:51.000Z","url":"/2022/07/29/jian-pan-an-jian-dui-ying-ascii-ma-ji-lu/","categories":[["undefined",""]],"content":"洛谷博客表格较为鬼畜,此文章将同步发表在 CSDN 上。 字母键及主键盘数字键 键名称 键代码 A ~ Z 65 ~ 90 0 ~ 9 和 ! ~ ) 48 ~ 57 小键盘数字及符号键 键名称 键代码 0 ~ 9 96 ~ 105 * 106 + 107 Enter 108 - 109 . 110 / 111 功能键 键名称 键代码 F1 ~ F12 112 ~ 123 双符号键 在主键盘,有上和下之分的符号。其中 a Misplaced &\\Large & b 表示为符号 a 在下符号 b 在上(例 < Misplaced &\\Large & ,)。 键名称 键代码 ; Misplaced &\\Large & : 186 = Misplaced &\\Large & + 187 - Misplaced &\\Large & _ 189 . Misplaced &\\Large & > 190 / Misplaced &\\Large & ? 191 ` Misplaced &\\Large & ~ 192 [ Misplaced &\\Large & { 219 \\ Misplaced &\\Large & | 220 ] Misplaced &\\Large & } 221 控制键 键名称 键代码 BackSpace 8 Tab 9 Clear (?) 12 Enter 13 Shift 16 Ctrl 17 Alt 18 Caps Lock 20 Esc 27 SpaceBar(空格) 32 Page Up 33 Page Down 34 End 35 Home 36 Left Arrow 37 Up Arrow 38 Right Arrow 39 Down Arrow 40 Insert 45 Delete 46 NumLock 144 "},{"title":"模板大全","date":"2022-07-29T07:55:44.000Z","url":"/2022/07/29/mu-ban-tai-quan/","categories":[["undefined",""]],"content":"整理封装自 ryanright 的博客 高精度 ST 表 并查集 线段树 树状数组 普通平衡树 "},{"title":"CF1644A Doors and Keys 题解","date":"2022-07-29T07:55:36.000Z","url":"/2022/07/29/solution-cf1644a/","categories":[["undefined",""]],"content":"题意简化 六个字母,任意一字母大写若出现在小写的前面,输出 NO,否则输出 YES。 Solution 字典暴力模拟,这样能够减少代码量。使用 toupper() 使代码更整洁。 "},{"title":"CF1644B Anti-Fibonacci Permutation 题解","date":"2022-07-29T07:55:29.000Z","url":"/2022/07/29/solution-cf1644b/","categories":[["undefined",""]],"content":"翻译已交,直接上正解。 Solution 显然,直接 dfs 生成排列-测试会超时。 想到可以在 dfs 过程中进行测试(判断下一个放置的数字是否满足反斐波那契序列的条件)。 于是代码就长这样: 46ms,AC。 But,你认为这就结束了吗? Solution++ 以上方法时间复杂度玄学(不想算,反正有 ,系数还蛮大),但通过数学分析可以降至裸 。并且代码量少很多 将排列降序。任意选择第 位数,那么这个数就是 。向前数两个数,分别是 和 。显然,。 将前两个数字相加,关于 的方程 的解为 。 若不是反斐波那契数列,就应该满足 。与 相矛盾。说明逆序排列是反斐波那契数列。 那么,如果我们调换一下前后相邻的两个数的顺序? 那么,序列就会变成: $$ (n-i+4),(n-i+3),(n-i+1),(n-i+2),(n-i+0),(n-i-1) $$ 事实上,可能没有 ,但没有可以不用管这个数字了,所以不会有问题。 如果有的话,调换顺序会波及到这些数字。 一一列出方程,解就完事了! ,不成立。 ,不成立。 ,不成立。 (想必你能猜到是这个吧),不成立。 都不成立,说明在倒序的基础上对调数字,都满足反斐波那契数列。 所以,总共可以调转 次,加上原来的逆序 次,就有 次了。 满足了题目条件。 这也就为什么题目上会有 的原因吧。 附:中间为什么会有一个 的解呢? 理性的认识,中间的两个数对调,移项了,所以有两点贡献,相比逆序的解应该少 。 这下,其他的解为 应该也不难理解了吧。 Solution+ 事实上,这道题有许多方法,最终原理就是 逆序排列永远满足反斐波那契数列。 方法1 逆序后,将任意一个数提前,也是 种。 方法2 逆序后,调换间隔一个数的两个数。(猜测) 附上 Translate。 Translate 反斐波那契数列(anti-Fibonacci)定义为 的排列中不满足 的排列。 输入 数据,每组数据给定序列长度 。 对于每组数据,只需任意输出 个长度为 的反斐波那契数列。每行一个序列,用空格分隔。(不允许输出多个相同的序列。易证长度为 的反斐波那契数列数量必定大于等于 。) 其中 。"},{"title":"CF1642A Hard Way 题解","date":"2022-07-29T07:55:21.000Z","url":"/2022/07/29/solution-cf1642a/","categories":[["undefined",""]],"content":"Solution 关于某一条线段是否是安全的(以下不考虑端点),有两个结论。 不是平行于 的线段必定是安全的; 若这条线段中较低的点(即 坐标较小的点)下方没有其他边,那么这条线段必定是安全的。 第二条结论显而易见,可以直接从三角形正下方的点通过直线到达。 第一条结论,斜着的线段无论多斜,我都可以从线段两侧中任意选择一侧的点到达。 如图, 为原线段,延长 至 交 轴于 。在 左侧任意找一点 都可以通过直线到达 上的点 ©。 结合下两个结论,只有一种可能有不安全的线段。即: 一个三角形中,有一条线段平行于 ,并且还是三角形较高的边。 比如样例第三组数据, 就是符合这些要求的三角形。 解法已经有了,如何更好的写更简单的代码呢? 用 struct 存端点,用 sort 简化代码。 code 我有一个小疑问,题目中对浮点误差的处理有何意义?反正都是整数"},{"title":"Codeforces Round 774","date":"2022-07-29T07:55:14.000Z","url":"/2022/07/29/774-solution/","categories":[["undefined",""]],"content":"A. Square Counting 给你一个序列 ,每一个元素满足两个条件: 已知 和序列之和 ,求对于任意 , 的个数。 组数据。 可以证明结果唯一。 结论: 题目中,首先看到了 结果唯一。所以证明的起点就在这里。 因为 范围内的数至多有 个,最小总值为 ,最大总值为 ,所以数列中的 不能被 范围内的数代替,因此答案唯一。 B. Quality vs Quantity 涂色问题。有一个序列 ,可以有三种状态:标记为红色,标记为蓝色,不标记颜色。 设标记红色的元素集合为 ,绿色为 。 那么,是否能够满足 且 ? 能输出 YES,不能输出 NO。(虽然输出 yEs 和 YeS 是一样的) 贪心。想要 和大于 和,而且 数量还得更少,那么只能让 中的元素远远大于 中元素。 那么排一遍升序,从左到右选,左边选 个数当做 ,右边选择 个数当做 ,如果扫完全序列都不能满足,那必然是 nO 了。 单次 ,均摊总时间复杂度 。 C. Factorials and Powers of Two 称一个数为强数,当且仅当这个数为 或 ,其中 。( 为非负整数集合) 求一个数最最少可以被分解为多个强数之和? 如果不可以被分解,那么输出 。 首先, 是不可能的。因为任意一个非负整数都可以转换成对应的二进制。而对应二进制位上的 ,单独拿出来,就都是强数。 比如 。 那么,现在就想,如何使 (即分解个数)最小了。 若直接枚举强数相加,那么时间复杂度为 。比较危险。 但是,发现只要确定阶乘的强数,反过来就可以推出二次幂的强数个数。 所以,可以只枚举 次就可以了。 ( 来自何方? 的逆阶乘小于等于 。) "},{"title":"Codeforces Round 775","date":"2022-07-29T07:55:06.000Z","url":"/2022/07/29/775-solution/","categories":[["undefined",""]],"content":"A. Game 有 个横向排列的位置,序号为 ,每个位置可能有水,也可能是空的。 向相邻格子移动是不需要花费的。 在每组数据中,你只能跳一次。你可以跳任意格远。代价为 ( 为终点 为起点) 你不能跳到含水格子里。保证起点 和终点 没有水。 只能跳一次,那么说明我们只可能通过一次大跳来跳过所有含水格子。大跳的代价与距离成正比,所以大跳的距离越小越好。 那么,大跳就从最左边的水格子前起跳,跳到最右边的水格子后即可。 B. Game of Ball Passing 传球游戏。在游戏的过程中,有 个人。他们将要互相传球。每个人传出球的次数是给定的(传入不算次数)。 那么,最少需要多少个球可以满足这些传球的次数呢? 比如说,第一组样例就可以只用一个球传出这种方案。 而第二组样例则不行。 重点在于如何利用 “每个人传出球的次数是给定的(传入不算次数)。” 找出踢球数最大的人,这个人的踢球数可以消耗其他人的踢球数。 若其他人的踢球数总和大于踢球数的人,这些人可以自己内部对踢(无论是一对一还是多对多,反正剩下的踢球数等于最大踢球数)。 但如果最大踢球数的人踢球的数量太大了,他跟其他人消耗后,还剩下了一些球数,只能他自己踢了(为什么?最多的情况下,即剩下人不内部踢球,只与最大踢球数的人踢,也只能消耗这些,还差一些)。 所以, "},{"title":"Codeforces Round 776","date":"2022-07-29T07:54:59.000Z","url":"/2022/07/29/776-solution/","categories":[["undefined",""]],"content":"A. Deletions of Two Adjacent Letters 一个字符串,长度为奇数(长度不大于 ),只可以在其中删除连续的两个字符。问是否能使删剩下的字符(必须删到一个字符)为给定字符? 能则输出 YES,不能则输出 NO。 如果这个字符处在偶数位上,那么他的左边或者右边就都有奇数个字符,不可能通过删去连续的两个字符来留下这个字符(左右不能跨分界线删除)。 注意同一个字符可能出现多次。模拟即可。 B. DIV + MOD 定义函数 ,其中 为系数。 给定系数 ,给定 范围 ,求 在范围内值的最大值。 其中 ,。 显然在范围区间内变化大的是右边的 (为什么?)。 但也会出现 变化的情况。那么,最大值就有两种情况了(即两个大幅度的变化区间,下见图片): 在小于等于 的数中除以 的余数最大。 数 。 那么,若存在情况 1,则取最大值。若不存在,直接取情况 2 即可。 C. Weight of the System of Nested Segments 在一个数轴上,有一些整点。称一些数为 包含系统 ,当这些坐标配对 时,任意 有 。 共有 个点,取出其中 个点,使得这些数配对 组后代价和最小。 一个配对的代价为 。 给出每个点的坐标 和代价 。求最小代价和和匹配数字的序号(序号就是输入的顺序,从 开始)。 不超过 。 只要取出 个点,都可以说明这些点可以配对(从左到右,从右到左依次配对)。 所以,我们只需要以代价排一遍序,左边取 个数,再以坐标为关键字排序配对即可。 "},{"title":"CF1650A Solution","date":"2022-07-29T07:54:51.000Z","url":"/2022/07/29/solution-cf1650a/","categories":[["undefined",""]],"content":"Solution 如果这个字符处在偶数位上,那么他的左边或者右边就都有奇数个字符,不可能通过删去连续的两个字符来留下这个字符(左右不能跨分界线删除)。 注意同一个字符可能出现多次。模拟即可。 "},{"title":"CF1650B Solution","date":"2022-07-29T07:54:44.000Z","url":"/2022/07/29/solution-cf1650b/","categories":[["undefined",""]],"content":"Solution 显然在范围区间内变化大的是右边的 (为什么?)。 但也会出现 变化的情况。那么,最大值就有两种情况了(即两个大幅度的变化区间,下见图片): 在小于等于 的数中除以 的余数最大。 数 。 那么,若存在情况 1,则取最大值。若不存在,直接取情况 2 即可。 "},{"title":"CF1650C Solution","date":"2022-07-29T07:54:36.000Z","url":"/2022/07/29/solution-cf1650c/","categories":[["undefined",""]],"content":"Solution 只要取出 个点,都可以说明这些点可以配对(从左到右,从右到左依次配对)。 所以,我们只需要以代价排一遍序,左边取 个数,再以坐标为关键字排序配对即可。 "},{"title":"CF1649A Solution","date":"2022-07-29T07:54:29.000Z","url":"/2022/07/29/solution-cf1649a/","categories":[["undefined",""]],"content":"Solution 只能跳一次,那么说明我们只可能通过一次大跳来跳过所有含水格子。大跳的代价与距离成正比,所以大跳的距离越小越好。 那么,大跳就从最左边的水格子前起跳,跳到最右边的水格子后即可。 "},{"title":"CF1649B Solution","date":"2022-07-29T07:54:21.000Z","url":"/2022/07/29/solution-cf1649b/","categories":[["undefined",""]],"content":"Solution 重点在于如何利用 “每个人传出球的次数是给定的(传入不算次数)。” 找出踢球数最大的人,这个人的踢球数可以消耗其他人的踢球数。 若其他人的踢球数总和大于踢球数的人,这些人可以自己内部对踢(无论是一对一还是多对多,反正剩下的踢球数等于最大踢球数)。 但如果最大踢球数的人踢球的数量太大了,他跟其他人消耗后,还剩下了一些球数,只能他自己踢了(为什么?最多的情况下,即剩下人不内部踢球,只与最大踢球数的人踢,也只能消耗这些,还差一些)。 所以, "},{"title":"CF1646A Solution","date":"2022-07-29T07:54:14.000Z","url":"/2022/07/29/solution-cf1646a/","categories":[["undefined",""]],"content":"Solution 结论: 题目中,首先看到了 结果唯一。所以证明的起点就在这里。 因为 范围内的数至多有 个,最小总值为 ,最大总值为 ,所以数列中的 不能被 范围内的数代替,因此答案唯一。 "},{"title":"CF1646B Solution","date":"2022-07-29T07:54:06.000Z","url":"/2022/07/29/solution-cf1646b/","categories":[["undefined",""]],"content":"Solution 贪心。想要 和大于 和,而且 数量还得更少,那么只能让 中的元素远远大于 中元素。 那么排一遍升序,从左到右选,左边选 个数当做 ,右边选择 个数当做 ,如果扫完全序列都不能满足,那必然是 nO 了。 单次 ,均摊总时间复杂度 。 "},{"title":"CF1646C Solution","date":"2022-07-29T07:53:59.000Z","url":"/2022/07/29/solution-cf1646c/","categories":[["undefined",""]],"content":"Solution 首先, 是不可能的。因为任意一个非负整数都可以转换成对应的二进制。而对应二进制位上的 ,单独拿出来,就都是强数。 比如 。 那么,现在就想,如何使 (即分解个数)最小了。 若直接枚举强数相加,那么时间复杂度为 。比较危险。 但是,发现只要确定阶乘的强数,反过来就可以推出二次幂的强数个数。 所以,可以只枚举 次就可以了。 ( 来自何方? 的逆阶乘小于等于 。) "},{"title":"CF1651A Playoff Solution","date":"2022-07-29T07:53:51.000Z","url":"/2022/07/29/solution-cf1651a/","categories":[["undefined",""]],"content":"Transplate 这些数将进行淘汰赛。规则如下。 第一轮比赛由相邻两个数比较。即 。 之后比赛由上一轮比赛的胜出者进行比赛。 两个数加和若为奇数,那么小的数胜利;若为偶数,那么大的数胜利。 问最终留下来的数是哪个数? Solution 第一轮比赛,留下来的数都是奇数。 (为什么?第一轮加和都为奇数,而较小的数都是偶数) 之后每一轮的比赛留下来的都是较大的数。 (为什么?奇数相加都是偶数,所以大的数赢) 那么,最终留下来的就是数列中最大的奇数:。 "},{"title":"CF1651B Prove Him Wrong Solution","date":"2022-07-29T07:53:44.000Z","url":"/2022/07/29/solution-cf1651b/","categories":[["undefined",""]],"content":"Solution 题目要求对于任意 都要满足 。 有绝对值,不妨 。所以有 解得 所以只要让数等于前面那个数的三倍即可。初始数为 。(升序,对于任意 都满足,因为是绝对值对称的) 注意到,样例中有输出 NO 的情况。是什么原因呢? 题目中有限制 。实际上最大的数应该是 。所以 , 即 那么 Code 长这样: "},{"title":"CF1654A Solution","date":"2022-07-29T07:53:36.000Z","url":"/2022/07/29/solution-cf1654a/","categories":[["undefined",""]],"content":"Solution 发现只要选择任意两个数,都可以通过一次操作将他们两个放在相邻的地方。 若设处理的两个数为 和 , 如果 ,只要翻转 即可。 如果 ,只要翻转 即可。 那么,只要找到序列中最大的两个数,加和输出即可。 时 ,空 。 "},{"title":"CF1654B Solution","date":"2022-07-29T07:53:29.000Z","url":"/2022/07/29/solution-cf1654b/","categories":[["undefined",""]],"content":"Solution 初看这道题,诶,有点难度,果然是 Div.1 + Div.2 的难度啊,AC 自动机? 啊不不不,完全可以不用 AC 自动机。 可以发现,只需要查找第一个字母是否出现在后面即可。 设字符串为 。 如果 在后面出现过,那么发现 实际上也会在后面出现。 实际上 也都出现。(虽然都是废话) 所以只需要依次删除字符串的第一个字符,只要在后面找到,就说明这个字符必定是在当前最长前缀里头的,且之后的字符都可以依次删除。 那么, 时 ,空 。 "},{"title":"CF1654C Solution","date":"2022-07-29T07:53:21.000Z","url":"/2022/07/29/solution-cf1654c/","categories":[["undefined",""]],"content":"Solution 暴 力 是不可能不打的。 这道题目有两种暴力方法。 一种从合并角度看,将相邻的两个数依次合并,看是否能合并完成。 但我选择的是更直观的暴力打法。 将总和依次分解,想到每一次的分解结果要是有对应的数字就消掉,剩下的分解,那么用 map 维护当前还需要处理的对应数字,一个 bfs 可以解决。 请注意,若分解个数大于 次后,必然是有些数字分解不了,那么这时候直接 return,以减小空间 & 时间。如果不处理会 TLE。 空间 ,时间 。 "},{"title":"P8102 Cow Insertion Solution","date":"2022-07-29T07:53:14.000Z","url":"/2022/07/29/solution-p8102/","categories":[["undefined",""]],"content":"听着《打上花火》,不知不觉推出了式子 初碰此题,看见 ,感觉 能过啊 () 心想可能得卡个常数了(事实后来我是大常数选手) 看到题面立马想到插入 的影响是有限的,大概是向左向右 个数。 整个题目都在求 ,干脆将所有 得到的数单独算出来。想到算定长最值,可以用 滑动窗口 解决,所以将值设出来: 那么未插入 的答案即为: 现在考虑插入 之后答案将会变成什么。 如果将 插入到 后面,序列长这个样子: 那么左端没有覆盖到 的地方是不会受 的影响的。 有右边界 ( 的右端点刚好与 重合) 所以右边界为 。 所以左端未受影响的答案为 同理, 右端左边界 , 则右端未受影响的答案为 现在需要处理中间受影响的部分。 观察到覆盖 的地方有个共同点,就是他们对答案的贡献为原长度为 的贡献与 取 。 将长度为 的 结果列出来: 与 相似。 那么, 的最终贡献为 左边界为 (刚好 踩到原来 的位置) 所以 。 右边界同理,。 所以贡献为: 所以加入 的最终答案为: 即 此时可以直接通过求出 即 (需要先进行 操作)的前缀和, 枚举求解 。 但是,式子有点乱。 将 ,得到加入 的贡献: 于是可以得到一个用 std::vector 实现的超大常数 code: "},{"title":"我所保存的链接","date":"2022-07-29T07:53:06.000Z","url":"/2022/07/29/wo-suo-bao-cun-di-lian-jie/","categories":[["undefined",""]],"content":"2022/6/16 Kth-Number-BFPRT-zhihu Kth-Number-BFPRT 2021/12/29 OpenSSH-Github"}]