比赛记录(1~10)
1 2023年最后一哆嗦
1 得分
题目 | T1 | T2 | T3 | T4 | T5 | T6 | 总和 |
---|---|---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
根据题目所示的不等式,我们会得到:
也就是说,
由此可得,
由于
另解:
在枚举
对于这个线性同余方程组,采用 exCRT 求解即可。
T2
考虑先求出所有
又由于
因此原式可以转化为:
然后考虑换元,即令
然后处理这个式子就很模板了,最后结果为:
线性筛求解即可。
T3
最简单的一集。
考虑容斥原理,即
快速幂求解即可。
T4
首先想到的是贪心,但很明显不对。考虑 dp。
在结构体中记录下标和原数据,从小到大排序(因为小数的影响更小)。
接下来考虑 dp,设
为什么这一段是对的呢?
考虑一种情况:设
,原序列为 ***ab
,则ba***
要比ab***
答案更优。因此这样做是正确的。
则对于当前一个数,放到两个端点之一肯定更大。
因此有状态转移方程:
初始状态就是
T5
首先很明显的是将每个数与
接下来对于每一个数与前一个数求差,即考虑差分。令
时,由于左右端点不能重合,所以明显不成立,直接输出 ; 时,他必须作为一个新的左端点,左端点数量加一; 时,他可以不进行操作,也可以既当左端点又当右端点,答案要乘上左端点数量加一; 时,他必须与前面任意的左端点匹配,答案要乘上左端点数量,同时左端点数量减一;
于是我们记录左端点数量
T6
简单的肯定是设
考虑一种新的状态,分别设:
-
表示第 步在终点; -
表示第 步与终点同行(不在终点) ; -
表示第 步与终点同列(不在终点) ; -
表示第 步与终点没有关系;
则分别应有转移方程:
答案就是
3 挂分
今日无挂分。
2 2024.2.6 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
考虑统计区间的方式,想到双指针。
维护两个数组
容易发现
最后统计答案,如果有
T2
发现第一个操作是完全平推的。
维护一个数组
这样可以在较小的复杂度内求出答案。
注意开 long long
。
T3
依然是找区间,依然考虑双指针。
我们发现一个性质:如果区间
我们用双指针来模拟这个过程。
至于如何快速求区间
T4
将字符串哈希变成数字,然后这道题就是 SDOI2009 HH的项链 这道题了。
当然还有很多其他做法,例如莫队、CDQ 分治等等。
3 挂分
- T2 操作完未清空
数组, 。
3 2024.2.18 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
Solution 1:
暴力分解所有数的质因数,对于
复杂度
Solution 2:
对于每一个
复杂度
T2
Solution 1:
将贡献拆成横坐标和纵坐标。对于每一个坐标而言,比当前机器人坐标小的要被减去,大的要减去机器人坐标。我们先对两个数组分别排序,求出前缀和。然后二分查找出机器人的坐标,利用前缀和直接累加即可。
复杂度
Solution 2:
仍然延续上面的思路,我们可以将所有坐标存进一个 BIT,这样对于每一个坐标区间查询即可。当然你用线段树也行,不过常数可能太大,会 T。
复杂度
Solution 3:
预处理出在每一列(每一行)时,其左右(上下)以及这一列(一行)的点的个数。这样在询问坐标的时候可以直接
复杂度
T3
Solution 1:
一个 naive 的想法是,对于每一个字符串跑一遍 KMP,然后利用拓扑排序一次次向上递推,求出最后的结果。只能得到
我们这个想法并没有错,但是在嵌套字符串的过程中,相邻两个字符串之间也有可能产生贡献。因此需要判断这个。
实现起来细节非常多,复杂度我也不知道。
Solution 2:
另外一个 naive 的想法是,直接暴力展开求出最后的字符串,暴力跑一遍 KMP 即可。可以得到
我们依然考虑这个想法。考虑记忆化搜索。
设
我们每一位每一位扫描,如果是小写字母,那么就进行朴素的 KMP;如果是大写字母,就要往下进行搜索。
为了使搜索完之后可以返回模式串的匹配位置,我们在设一个数组
最后跑一遍 DFS(F,0)
,结果就是
复杂度
T4
60 pts:
考虑设
100 pts:
考虑容斥。互质数量 = 总数 - 不互质数量。设
其中
这个式子求解的方式很多,暴力、线筛等等都可以。
复杂度
3 挂分
- T1 中不小心将
num
写成了cnt
, 。
4 2024.2.19 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
直接暴力枚举出所有小于
然后做法就很多了,有预处理、双指针、二分等方法。复杂度就是
T2
Solution 1:
设
那么有状态转移方程:
暴力转移即可。初始状态
Solution 2:
设
则有状态转移方程:
暴力转移即可。
两者复杂度均为
T3
10 pts:
考虑暴力 DFS。直接枚举每一个位置放还是不放。
可以优化该算法,这样甚至能过掉样例:我们改为枚举每一列放多少个点,利用组合数计算即可。
100 pts:
首先要发现一个性质:对于在模
也就是说对于点的个数来讲,他们每
因此我们不必枚举所有的
考虑 dp。设
那么这样的复杂度是
我们可以令
T4
(p.s:此题我在考场上想出了正解,然而只剩最后
我们发现,只有删去的边是在最短路上的,才能让他迟到。
然而这也不是一定的,因为可能有多条最短路。
我们先跑一遍最短路,然后记录每个节点在最短路中可能的前置节点。这样我们就可以直接从终点跑一遍 DFS,建出一张新的“最短路图”。
在这个最短路图上,我们会发现,满足让他迟到的边一定是一条割边。因此我们再跑一遍 Tarjan 就可以求出答案。
个人感觉比 T3 简单(可能因为我 dp 太烂)。
3 挂分
今日无挂分。
4 2024.2.21 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
首先我们可以推出一个式子:对于
考虑将其推广到更高元,仍然成立。
根据这个结论,我们就可以直接来做这道题。将数列排序,前一半用大乘小,后一半相邻的数相乘。最后两者作差即为答案。
T2
看到 最小覆盖最大
,直接可以想到二分答案。
二分最后的 size,然后考虑怎么检查。贪心是不行的,考虑 dp。
设
注意后一种是不可选的情况。
我们发现
T3
首先考虑一个经典典中典的树上技巧:up and down。
具体的,设
首先看
接下来看
最后我们来看答案的式子。对于一条边,我们只需要统计两个点选或不选的总方案数即可。至于怎么求,利用
这是我们发现,公式中有除法,结果还要取余,因此只能用逆元求解。
T4
太难了,咕咕咕。
3 挂分
今日无挂分。
5 2024.2.22 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
Solution 1:
暴力维护每一行滚动的上面的数,每一次判断是否有重复的情况,然后直接暴力计算循环节即可。
Solution 2:
容易发现每次横向滚动以
T2
30 pts:
容易发现这是二分图匹配,暴力计算即可。
100 pts:
首先容易证明,对于一个男生要选个子比他高的,选尽可能低的那一个对于后面的男生更有利。
因此我们考虑贪心,将两种人分开考虑,一个升序一个降序排列,利用贪心求解即可。
T3
首先我们发现,最小生成树的边权之和是
因此所有最小生成树的边权和都是
又因为父亲的编号小于儿子的编号,因此一个点的父亲的方案数就是小于他且与他互质的数的个数。显然这就是欧拉函数的定义。
因此最后答案就是
T4
折半搜索的模板题。
考虑爆搜的复杂度是
我们考虑将区间分成两段,这样复杂度就是
我们记录下两段区间分别可以凑出的数
显然直接枚举
3 挂分
- T1 移动骰子时的转移写错,
。 - T3 忘记了
函数,导致离正解只有一步之遥。
6 2024.3.10 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
此题就是一个模意义下的背包,设
暴力计算即可。
T2
又是典中典的 up and down。
第一遍 DFS 可以直接维护子树内最长链,然后在第二个 DFS 中求出子树外最长链。但是这样会有一个问题,如果在第二个 DFS 时,这个节点就是父节点的最长链上的节点,那么就不能简单的用最长链更新。解决方法也很简单再记录一个次长链即可。
记子树内最长链为
T3
首先列出这样一个显然的式子:
显然
其中,我们可以直接枚举
T4
首先,
但是我们会发现这样不好实现,因此在加入一维。设
接下来我们分析。
如果现在不连
如果现在要连
最后我们考虑转移到下一个点,只有当
此时方程为
初始化是
3 挂分
- T1 写了一个非常傻逼的
复杂度,还没发现。 - T2 又差一步推出 up and down。
7 2024.3.24 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
首先求出连通块,暴力 BFS 即可。
记录“四至点”,然后看暴力到的点数和矩形的点数是否相同即可。
T2
首先,这道题的答案就是概率。每个数列的贡献为
记
然而帕琪七重奏只需要构成
现在计算在整个长为
T3
本题按照部分分做基本可以拿到满分。
最开始的一步:发现
直接暴力枚举
发现由于
从这里开始就是提示正解了。
首先,如果确定
由于有
我们再记
此时枚举
我们记
考虑对上面的算法再进行一些优化。
如果我们考虑只枚举
此时
此时我们发现,令
因此我们可以在正序枚举
然后再倒序枚举
T4
首先看到这个题目的描述自然会想到区间 dp。
然后我们又发现
考虑如何设计状态。设
我们枚举断点
其中
但是还有一种特殊的情况,即如果整个区间本身就能合并为一个字符的情况。那么我们又会有转移方程:
但是又有一个问题,当
3 挂分
今日无挂分。
8 2024.4.5 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
首先,根据约数和定理,一个数的正约数之和为
显然枚举是不好实现的,但是我们还有一个强有力的工具——爆搜。
我们在一层内枚举
然后剩下的就是细节:
- 我们无法枚举
之内所有质数,枚举到 左右即可。剩下的质数需要单独特判。 - 注意循环的时间复杂度,需要优化。
T2
一道比较简单的概率。
首先我们肯定是设
问题在于这道题的钱数和次数是相关的,而且次数也不容易求出。
因此我们再设
- 当这一张以前抽到过,则
; - 当这一张以前没有抽到,则
;
二者相加即可。但是此时右边还有
那么有了
- 当这一张之前抽到过,则
; - 当这一张以前没有抽到,则
;
这个式子看起来有点鬼畜,解释一下:以第二个为例,
此时仍然需要移项,后得:
暴力计算两个数组即可。
T3
个人认为最难的一道题。
首先关注构成的树的总个数,显然是
接着我们考虑如何计算路径之和。这里采用非常典的拆贡献,对于每条边,走过它的次数就是
接下来考虑如何求总的结果。此时我们并不需要具体求出
下面先看一段证明:
考虑这样一件事:对于一个点,其子树大小为
,那么还会有多少个剩下的位置可以放? 引理:每多放一个点,就会多一个位置。
证明:显然。对于放下的那个位置,会使得位置减一。但同时这个点的两个儿子又使得位置加二。因此位置加一。
于是对于上面的问题,答案就显然为
。 同时如果子树外有
个点,那么位置就是 。
此时我们设
- 当
号点没有放在 的子树内,则此时剩下的位置数量就是 ,于是方案数为 。 - 当
号点放在 的子树内,则此时剩下的位置就是 ,于是方案数为 。
综合起来得:
此时我们发现一个严重的问题,这样的复杂度是
接下来考虑初值,显然有
最后我们将方案数乘上边的次数即可,答案就是
T4
正常想法:
首先考虑转化为每条边期望经过的次数,对于一段区间,显然是
将其拆开得
由于题目中提到了要区间修改,区间查询,那么我们首先想到线段树。
再考虑上面的式子,我们只需要维护
但是这样我们前面的系数不能随着区间来变化,因此我们实际处理中还要进行一些加减。
非正常想法:
首先,打表出每一个区间长度下每一个收费站期望经过的次数:
不难发现第
因此我们可以写出通用的式子:
对于这个式子,展开处理,后面就与正常做法相同了。
3 挂分
今日无挂分。
9 2024.5.2 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
大模拟题。
直接按照题意维护即可。利用栈判断循环的开始和结束,同时统计复杂度。注意
T2
分层赋分题。
将题目看做在矩阵中选点,则每一行只能有一个点。
36pts: 暴力枚举每一行的点在第几列(或不选),判断即可。复杂度
64pts:
考虑到
那么显然会有状态转移方程 :
最后答案为
到此就是暴力方法能够拿到的最好分数了。下面开始正解。
84 pts:
考虑到如果不合法,那么只可能有一列超出总数的一半。
而这样就意味着不合法情况是好求的,那么可以考虑容斥,用总方案数 - 不合法方案数。
先看总方案数。每一行可以任意选一个或者不选,令
接下来是不合法方案数。由于不合法的列只可能有一个,我们就先枚举它。设当前枚举到的列为
仍然考虑 dp,设
最后答案为
100pts:
考虑到上面的步骤中哪里最浪费时间,显然是 dp。我们发现我们的最终答案对于
那么我们便可以将后两维合并成
最后答案为
T3
首先发现
我们设
这里
那么显然我们现在要解决两个问题:
先看
不妨再设一个数组
接下来考虑
那么
接下来考虑求解 dp 数组,按照朴素的算法我们需要枚举两次子集,这样算是
我们考虑下面这种奇妙的技巧:
for (int T = S; T; T = (T - 1) & S)
感性证明:
我们其实可以直接观察 T 的变化,立马就能理解。设
,那么 T 的二进制变化就如下:
。 可以观察到枚举是没有浪费且不重不漏的。
复杂度说明:
首先我们在该循环的外层枚举了
,而内层本质上是选出含有 的子集。设总共有 个 ,则内层的复杂度就是 。 考虑到外层实际上就是在
个数中随便选 ,因此总的复杂度我们可以写成 。那么我们改写成 。根据二项式定理可得这就是 ,即 。 因此这一部分的复杂度其实是
。
那么通过上面的分析,我们就通过这样的优化将复杂度优化至
最后复杂度是
T4
我们可以想到用子树来更新当前的值。假如当前节点是
我们将
考虑到这里面有位运算操作,还要进行一系列合并维护,想到利用 01-Trie。
此时我们将上面的操作总结起来就是在 01-Trie 上进行全局加一、插入、维护异或和、合并。
我们先看全局加一,这关系到 Trie 的形态。
我们在二进制下举一些例子,观察加一后的变化:
我们发现,二进制下加一就是将二进制末尾连续的
这就启发我们 01-Trie 应该是从低位向高位建。接下来考虑具体如何在 Trie 上加一。
我们发现,无论怎么样,都是要将
这样做会发生进位,因此在插入的时候我们需要给前面填上几个
对于维护异或和,我们考虑从 Trie 树上子树的信息转移过来。对于
最后就是合并,我们可以将 Trie 看成一颗动态开点线段树,按照一般方式直接合并即可。这样的思想也可以说明上面维护异或和的方法:既然可以看做线段树,我们就可以进行 pushup
操作,也就是上面用子树信息更新。
最后我们在原树上进行 DFS,利用 01-Trie 维护即可。
3 挂分
今日无挂分。
10 2024.5.3 测试
1 得分
题目 | T1 | T2 | T3 | T4 | 总分 |
---|---|---|---|---|---|
得分 |
排名:rank
2 题解
T1
我们发现取出队列元素之后可以任意放置,那么我们就可以把在当前
形式化的讲,我们给每一个要送出的礼物在栈中的下标记为
这样我们只是对于每一个礼物进行遍历,复杂度
T2
首先考虑暴力。修改操作是
我们令每一位上最后可能得取值为
关注
这样做是
我们首先发现这样一件事:在求出
那么总共有
但是我们发现这样做运算量达到了
T3
玄妙。
50pts:
我们可以将整道题看做分组背包。我们可以将每一列看做一个组,耗费的空间就是打的次数,价值就是所得分数。
这样做看似非常合理,但是实际上没有任何道理。我们在打 Y 砖块的时候固然可以看做没有消耗子弹,但是当我们的子弹数量是
然而由于前 50pts 没有 Y,因此可以水过。
100pts:
我们首先来考虑一个借子弹的思想:
将第
列的子弹借给第 列,其实就是调换了顺序。 我们本来是先打
再打 ,但是我们可以在打 的时候让自己的手中空下几发子弹,给 列先打。在 列打的过程中可能打到 Y 砖块,这样它就会保留这几发子弹,然后再还给 打。 这样我们消耗的子弹数量一致,而且在保证打 Y 砖块时有子弹的前提下获得了更多分数。
现在我们回来看这道题。仍然考虑 dp,设
同时我们还需要两个辅助数组,设
现在考虑转移方程。我们先看
我们根据上面的分析,在打
接下来是
首先我们显然会有
- 当
给前 列借
此时我们最后一发打到的是
于是我们的转移方程就是:
- 当前
列给第 列借。
同理,这样最后一发打到的是前
然后我们直接转移即可。最后答案为
时间复杂度
T4
爆搜即可。
具体来讲,我们只需要判断顺子和带牌,剩下的我们都可以看成散牌,然后直接统计即可。
3 挂分
- T2 动态开点线段树空间开小,
。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期