02 2024 档案
摘要:A 题目大意 输入一个字符串,把这个字符串的最后一位改成 4 后输出这个字符串。 解题思路 直接模拟即可 AC 代码 #include<iostream> #include<math.h> #include<time.h> #include<stdio.h> #include<algorithm>
阅读全文
摘要:解题思路 一种不需要树形 dp 的做法。 因为是一颗无根树,所以我们不妨以重心为根。 首先考虑边权最少的情况。可以发现这个时候对于任意两个叶子节点,我们可以分别考虑其到根节点的路径,这样对于求其路径的异或值是没有影响的,但是在这种情况下我们可以很方便的讨论其路径的奇偶性。令 表
阅读全文
摘要:解题思路 显然,有以下两种选择的方法: 所有边一样长; 两条一样长的边,第三条边小于这两条边。 然后组合数计算即可。 AC 代码 #include<stdio.h> #include<stdlib.h> #include<algorithm> #include <vector> #define ll
阅读全文
摘要:解题思路 贪心,能走距离最短的城市就一定走。 分别考虑 和 的情况,两种情况分别是从后向前转移和从前往后转移,分别预处理一个前缀和和后缀和即可。 AC 代码 #include<stdio.h> #include<stdlib.h> #include <valarray
阅读全文
摘要:解题思路 因为可以有空集,那么我们首先构造第一段最长的连续上升的序列,那么这段序列中共有 个上升子序列。接下来我们考虑补全剩余的,我们不妨将剩余的部分全部设为连续不增序列,那么设当前位置在第一段中有 个小于它的,那么添加这个数后可以增加 \(2^{
阅读全文
摘要:解题思路 一个比较显然的结论: 若序列中存在一段连续的长度大于 的区间,且区间中的数均为 ,那么一定可以将整个序列转化为 。 进一步的,我们可以推出,若序列中有一段区间的中位数为 ,那么这个序列一定可以全部转化为 。 最后特判 和序
阅读全文
摘要:解题思路 其实是很简单的一道题,考虑计算出所有 在减去每一个 后所有可能的值,将这个值按照从小到大的顺序排序,那么我们可以考虑固定最小值,查找最大值,这个时候从最小值到最大值的区间内应该每一种 都出现了一次。那么,我们可以使用一个桶或者 map 搭配双
阅读全文
摘要:解题思路 简单贪心题,我们可以把整个序列看作 个可重集,首先可以得到一个显然的结论:较大的数一定比较小的数先放入一个集合中。同样,由于每一轮 ,其中 表示第 个集合的元素和,那么,我们一定会将当前的
阅读全文
摘要:解题思路 观察可以发现,每次操作后序列元素之和不变,那么我们可以将每一次操作看作是 向 移动了 。由此可得,若序列和 ,那么一定无解,否则一定存在一个合法的操作方案。 因为每次移动时移动的数应为 \(i
阅读全文
摘要:解题思路 与其考虑删除哪些点,不如考虑保留哪些点。考虑到和异或有关,那么我们可以把这些数倒序插入 trie 树中,然后我们就可以在 trie 树上跑一个简单的 dp: 若当前节点为叶子节点,那么保留,返回 ; 若当前节点在链上,那么直接继承儿子节点; 若当前节点有两个儿子,那么更新为较大儿
阅读全文
摘要:解题思路 没什么好说的,就是打表找规律…… 表在这里 不难发现,三元组中第一个数的最后两位按照 的顺序变化,其他位也一样,同样,第二个数和第三个数中每两位分别按照 和 \(00 \to 11\to 0
阅读全文
摘要:解题思路 简单贪心,优先选择叶子节点最多的,这样能够保证一定能把所有能删的都删了。 因为要建一个可删除的图,所以我们可以使用 set 来存边,不然就需要维护一堆东西……那么我们肯定是从有叶子节点的点向父亲更新的,那么我们每次选择叶子节点最多的点,然后删除 个叶子,判断一下删除后该节点是否
阅读全文
摘要:解题思路 其实多看几组也能发现块数等于交点的数量加上两个端点都在边上的线段数量再加一。 证明如下(图见样例): 对于两条只有一个端点位于边上的线段,因为保证有一个端点位于边上,那么这两条线段的交点一定会和已存在的点、边构成一个新的矩形; 对于其中有一条为两个端点均位于边上的两条线段,两个端点均位于边
阅读全文
摘要:解题思路 巧妙的数据结构题,非常巧妙的利用的线段树的奇妙性质。 操作逐条维护: Replace: 直接线段树上单点修改; Sum:线段树查询区间和; Reverse:考虑线段树的形态。线段树第 层(除最后一层)有 个节点,那么将所有 的区间
阅读全文
摘要:解题思路 第一眼看过去感觉不是很可做…… 但是我们可以发现,如果有两个点在不同的集合中出现过,那么一定会存在彩虹环,那么两个点最多出现一次。同时我们考虑将题意转化一下,变成求最大能选取的点,使得不出现彩虹环。根据刚刚的性质,我们可以考虑每个点向它所在的集合连一条边权为 的边,
阅读全文
摘要:解题思路 先考虑如何将一堆数变为相同的。 显然,这里有一个条件 ,证明如下: 每次操作只能将两个数变为相同的,那么一个数在使得其他数变为相同数的操作中(我们不妨将所有数进行这种操作称为一轮操作),一个数最多被使用一次; 按照错位操作,即第一轮 \(1\
阅读全文
摘要:解题思路 很简单的贪心。 观察发现以下性质: 当 时,这一行一定只有两个目标,且第二个目标一定位于一个 的格子内; 当 ,那么当前列右边某一列发生转向的地方, ; 那么这道题就基本已经做出来了。因为
阅读全文
摘要:解题思路 首先我们知道,当序列中有奇数个 的时候无解,因为每次操作只会增加或减少 或 个 ,当序列中有奇数个 的时候,一定会存在一个 无法被消除。因此,在这种情况下,直接输出 NO 即可。 不难发现,序列的异或和为一定值,证明如下
阅读全文
摘要:这么好的题为什么没有简单一点的乱搞做法啊! 以下来自某篇题解: 提一下几个要点: 1.是按照 从小到大排序。 2.能往后多查找几个点就多查找几个点(在时间允许的情况下)。 3.必须旋转,否则 分。 但是旋转是什么,蒟蒻不懂…… 这里提供一种对于蒟蒻更加友好
阅读全文
摘要:解题思路 不难的题,但是细节有亿点多…… 观察三组样例不难发现,我们可以把所有的信用卡的圆角去掉,变成一个长 ,宽 的矩形。考虑将这个矩形的四个顶点加入一个点集中,然后求凸包,答案即为这个凸包的周长加上一个半径为 的 ⚪ 的周长。
阅读全文
摘要:解题思路 增量法求三维凸包。 我们先选择一个面,将这个面作为当前凸包上的一个面,然后考虑不断地添加新的点,并更新凸包,最后用法向量计算每个面地面积,加起来即为答案。 那么如何添加点呢?我们将新的点看作是一个光源,那么光线打到凸包上,会有一些地方照到(两面),有一些地方没有被照到(暗面),同时会有一些
阅读全文
摘要:解题思路 其实还是很好想的,但是似乎有一点难写大概率是我写史了。 直接无脑分块。 我们将序列分为若干块后,直接每一个操作分别模拟即可: 区间修改: 我们对于整块直接给块赋一个统一的值就行了,对于零散块和在一个块内的则暴力修改; 区间反转: 我们对于整块打上一个反转标记,每次异或 ,对于零散
阅读全文
摘要:解题思路 分块做法 加法乘法打上标记,然后零散块下传一下就可以了。 开 long long 后减少取模次数可以有效减少运行时间。 然后加上快读就可以稳定 AC 了。 AC 代码 #include<math.h> #include<stdio.h> #include<stdlib.h> #define
阅读全文
摘要:解题思路 暴力做法 从 到 枚举每一个数,然后建线段树,记录最大下标,然后计算答案。 代码略。 时间 ,期望得分: 分。 优化暴力 我们考虑每次枚举不遍历整棵线段树。显然,贪心的,最深的最右边的节点编号最大。那么我们可以发现,如果两颗子树大小相
阅读全文