2022 NOIP 备赛记
前言
已经高二了,依旧是蒟蒻。应该是最后一次比赛了,所以打算拼一把。
就从国庆这一天开始写起吧。没啥逻辑,想到啥就说点啥,也算是记录一下一个信竞生的日常吧。
\texttt{2022.10.01}
大概是开始零碎的复习了。
先从树链剖分入手,大概是每天码一题的样子,但是弱智的错误还是接连不断。什么询问下标没用改成
树链剖分往往和线段树相结合,所以说下标的问题要值得注意,因为剖分大多依赖的是 if (dep[fx] < dep[fy]) swap (fx,fy),swap (x,y); 这个交换的顺序,认真的理解了一下,现在应该能明白了。while (fx != fy) 循环里的交换,默认
做题时遇到一类需要进行与边权相关的操作的题目,有一个比较好的处理技巧--就是把边权转到深度较大的点上。考虑一下正确性,每一条边都被两个点相连,所以一定能通过这种方式将边权全部进行转化,而每一个点的深度在第一个 modify (1,1,n,dfn[x] + 1,dfn[y]) 就能完美的解决这个问题。原因很简单,由树链剖分求
习题列表:
-
P4114 Qtree1 同 QTREE - Query on a tree 边权转点权,单点更新,区间查询。
-
P4315 月下“毛景树” 边权转点权,区间更新,区间查询。
-
P3038 [USACO11DEC]Grass Planting G 同 SP12005 GRASSPLA - Grass Planting 边权转点权,区间更新,单点查询。
-
P3178 [HAOI2015]树上操作 区间更新,区间查询。
-
P3833 [SHOI2012]魔法树 区间更新,区间查询。
-
CF343D Water Tree 区间更新,单点查询。
-
CF165D Beard Graph 单点更新,区间查询,最近公共祖先。
-
P3950 部落冲突 单点更新,区间查询,最近公共祖先。
-
P4116 Qtree3 轻重链剖分,
set。
\texttt{2022.10.05}
数位
ll dfs (int pos,bool limit,bool lead)
{
if (pos > cnt) return 条件;
if (!limit && ~dp[pos][sth.]) return dp[pos][sth.];
int res = limit ? a[cnt - pos + 1] : 9;ll sum = 0;
for (int i = 0;i <= res;++i) sum += dfs (pos + 1,(i == res) && limit,(i == 0) && lead);
if (!limit) dp[pos][sth.] = sum;
return sum;
}
一类题目可以直接进行记忆化,而一类题目需要通过合理的状态设计从而将其进行转移并记录。
习题列表:
-
P4127 [AHOI2009]同类分布 枚举各位数之和来充当模数,从而进行记忆化。
-
P4317 花神的数论题 枚举二进制数中
1 的个数,设f[i] 表示有i 个1 的数的个数,之后根据乘法原理用快速幂求解。 -
P6218 [USACO06NOV] Round Numbers S 记录
0 与1 的个数到达边界时进行比较即可。 -
P4124 [CQOI2016]手机号码 记录前两位数以及不能出现的数这四个信息。注意前导零的处理,可以直接循环枚举第一位然后再去搜索,同时需要判断位数(
L = 10^{10} 时,L - 1 的位数便不再符合)。
\texttt{2022.10.09}
国庆回来竟然就要月考,一通乱考,晚上还是来机房刷题。接着回到数据结构,再来看看树状数组。
说到树状数组,总是会与逆序对联系在一起,毕竟太经典了。同时,树状数组的题目往往伴随着离散化(要不就 +1 或 -1,估计也就没什么大的问题了。
一般来说,查询 query (x) 表示求小于等于 -1。又因为树状数组的区间查询是基于差分的思想,要减去左端点之前的部分,所以说也要 -1。似乎最常见的情况就只有这么多,先写这些吧。
由于线段树与树状数组都比较常考,接下来几天里,就做做有关的题目吧。
习题列表:
-
P6186 [NOI Online #1 提高组] 冒泡排序 与逆序对相结合,记录
k[i] 表示逆序对数为x 的位置的个数,然后通过找规律发现c 轮的排序会少\sum_{i = 1}^{c} k[i] 个逆序对,最后通过树状数组维护每次操作产生的影响。 -
P3586 [POI2015] LOG 通过找规律发现要维护的是
\ge s 的数的个数以及< s 的数的和。需要离散化,所以如果是在线操作的话应该用平衡树去维护。 -
P4054 [JSOI2009] 计数问题 二维树状数组,写起来和一位的差不多,同时再多开一维数组记录颜色的信息,查询的时候用差分的思想去解决问题即可。单点修改,区间查询。
-
P4514 上帝造题的七分钟 区间修改,区间查询。令
d[i] = a[i] - a[i - 1] ,则有\sum_{i = 1}^{k} d[k] = a[k] ,修改时分别处理l 与r + 1 即可。同样的,扩展到二维时,二维前缀和变为\sum \limits_{i = 1}^{x}\sum\limits_{j = 1}^{y}\sum\limits_{k = 1}^{i}\sum\limits_{l = 1}^{j} d[k][l] = \sum \limits_{i = 1}^{x}\sum\limits_{j = 1}^{y} d[i][j] \times (x - i + 1)(y - j + 1) = \sum \limits_{i = 1}^{x}\sum\limits_{j = 1}^{y} (x +1)(y + 1)\times d[i][j] + (x + 1)j\times d[i][j] - (y + 1)i\times d[i][j] + ij \times d[i][j] 。因此开四个树状数组分别维护这四个信息,最后还原差分序列即可。 -
P1637 三元上升子序列 比较简单的一道题,遍历中间的那个数字,然后正反两边循环分别用树状数组维护比其大(小)的数的个数,根据乘法原理得出答案。
-
P3605 [USACO17JAN]Promotion Counting P 容易想到退化成链时变为求逆序对的个数。类似的,离散化之后用树状数组维护比某一节点大的数的个数,用
dfs前后的值作差得到答案。 -
UVA12983 The Battle of Chibi 同 CF597C Subsequences 不难想到
O(kn^2) 的朴素\texttt{DP} ,dp_{i,j} 表示前i 个数中以i 结尾的且长度为j 的严格上升序列。然后发现dp_{i,j} 会由dp_{i,j - 1} 得到,因此可以用数据结构优化\texttt{DP} 。对于第i 个数,需要找到比它小且在它前面的节点,不难想到使用树状数组维护。同时,可以用滚动数组优化空间,得到最后的时间复杂度为O(kn \log n) 的代码。 -
P5200 [USACO19JAN]Sleepy Cow Sorting G 不错的思维题。手模就能发现,最少的数目是倒序第一个出现
a_i > a_{i + 1} 的i ,相当于i 之后的都已经有序,不需要移动。输出方案时,由于需要移到有序数组中的某一位置,因此需要知道移动时比它小的数的个数,用树状数组维护,对于每一个移动的量,答案为k - i + query (a[i] - 1)。 -
P3582 [POI2015] KIN 由于不能某个数多次出现,则不能累加它的贡献。考虑枚举并记录每种数上一个数出现的位置,如果一种数两次出现,那么我们就把上一次的位置修改成其相反数从而抵消贡献;如果大于两次,显然不能多减去贡献,那么把上一个位置之前的全部变为
0 即可。于是题目就转换成了区间最大子段和,线段树维护左右子树的最大子段和,区间和,最大子段和即可。
\texttt{2022.10.16}
贪心可知找到距离最近的一个电梯然后向上走即可,于是题目转化为求距离
由于成环的特性,直接进行线段树操作并不方便,考虑开三倍的数组,
最后在 query 的时候加了个优化,如果左区间返回非零值就可以直接结束,这样刚好能够使
【updated】 发现题解写了一个记忆化搜索就过了,我敲!
看了题解好像也不麻烦,看来对
由于
总的来说,这场模拟赛难度不大,但是却需要足够的细致才能一次写对,继续加油吧!
\texttt{2022.10.18}
开始状态压缩
-
P3694 邦邦的大合唱站队 由于
m 的数据范围极小,所以设dp_i 表示在i 状态小的最小出队人数即可。 -
P2704 [NOI2001] 炮兵阵地 首先预处理同行都情况,把合法的状态进行储存。之后处理列的情况,需要满足列也不冲突,因此状态中要加入前一行,枚举时需要从上两行开始处理。前两行比较特殊需要分开处理。
-
P2831 [NOIP2016 提高组] 愤怒的小鸟 预处理出两个点能构成的所有
c = 0 的二次函数,记录一次二次项系数即可,然后将所有过某抛物线的猪放入一个状态中。转移时每次加入一条抛物线更新状态,当然要注意某抛物线只过一点的特殊情况。实现起来有一定的细节,需要注意a < 0 。 -
P3092 [USACO13NOV]No Change G 枚举各枚硬币的使用状态,然后转移时通过二分找到上一次的购买的物品。
\texttt{2022.10.21}
又是模拟赛。
晚上打了
\texttt{2022.10.23}
再次模拟赛。今天的
停课了。
早上补题。
终于有时间把那些压箱底的题目给补了,通过了很是开心!!!
\texttt{2022.10.25}
上午打一场
补了昨天
上午复习数论。
重新推了一遍
了解到一个叫做米勒罗宾素数测试的方法,本质是运用费马小定理的逆定理。 随机出几个数
-
P1463 [POI2001][HAOI2007] 反素数 将数表示成算术基本定理的分解形式后,根据贪心,让小的质数的幂尽量大。不难发现,在该数据范围下,并不需要枚举过多的质数,直接搜索求解。
-
找出
n 个数两两之间最大公约数的最大值。
倒序枚举最大的最大公约数,然后利用桶判断该公约数出现的次数,一旦大于等于
- 现在给定一个整数
n ,需要找到一个大于n 整数m ,使得\mathrm{LCM}(1,2,\cdots,n) \mid \mathrm{LCM}(n + 1,n + 2,\cdots,m) 。
按照算术基本定理的分解形式,发现
- 求
\sum_{i = 1}^{n} \gcd (i,n) 。
枚举最大公约数
-
Minimum Modular 由余数的定义可知,若 所有剩下的数
\mod M 均不同,显然最小的M \in [n - k,\max \{a_i\}] ,由数据范围可知我们可以枚举M 。发现当a_i 与a_j 同余时,|a_i - a_j| \mid M ,所以我们可以预处理差值,然后将M,2M,\cdots,kM 的数全部进行统计,若在题目允许的修改范围内,那么我们就找到了最小的M ,输出即可。 -
已知若
x,y \in S ,则\gcd (x,y) \in S 。现在给出集合中一定存在的若干个数,需要求出集合的最小大小。
集合的最大数一定是所给中的最大值,于是我们又可以枚举每一个数,判断是否存在。对于一个输入中不包括的数
- 求
\sum_{i = 1}^{n} n \% i 的值。
原式可以变为
\texttt{2022.10.28}
【插播广告】 今天是巨佬
重温一下最短路。
拆点是个很好的做法,相当于是将一个点拆成不同状态的多个点,然后分别连边进行建图。
【例】 求将任意仅一条边的边权除以二后的
每一条边都为除或不除两种状态,因此可以用
赛前再次看下模拟退火,为了骗分。
明天
\texttt{2022.10.29}
开考,
接下来先写了
感觉发挥不大好,但是却发现我只要一慌乱就不能再仔细去分析题目了,所以在
估分:
\texttt{2022.10.31}
补题。
写点数据结构题。
写点构造题。
\texttt{2022.11.3}
-
GSS2 - Can you answer these queries II 求区间最大子段和(可为空),但是重复数字只算一次。不难想到离线处理,按询问的右端点进行排序。设当前的点为
i ,则该数所产生的影响的区间为[pre_i + 1,i] ,因此在更新后求出历史区间和的最值(以之前的一点最多到i 点的最值)。 -
P6018 [Ynoi2010] Fusion tree
\texttt{01 Tire} 的运用。对于每一个节点,开一个字典树。对于操作三,可以直接通过字典树求出子结点的异或和,由于只有一个父亲,直接单独处理即可。对于操作二,先删除再插入节点,同样的,对父亲单独进行处理,受到影响的是父亲的父亲节点。对于操作一,需要通过模拟可知,加一相当于在\texttt{01 Trie} 中交换左右节点,因此直接递归求解即可。 -
P1318 积水面积 单调栈,当且仅当左右区域均比其大时会产生积水。可以直接正序倒序处理出两个数组表示从左/右开始的最大高度,然后遍历判断
a_i 与最大高度的最小值的相对大小即可。 -
P4053 [JSOI2007] 建筑抢修 按时间排序后能加就加,不能加时若能够替换原有答案使得更优(也就是说当前修复时间比原有答案的最大值小时),则将其替换。可以使用优先队列或
multiset实现。
\texttt{2022.11.6}
周末按道理是去教室自习,但是还是来到机房,还翘了数学考试。
上午瞎做了点题目,中午打饭的大伯给了两块肉还说这已经很多了???(真的气死)
下午模拟赛。(在机房打题真的会降智嘛,怎么打弱智错误?)
出分了!
实际分数:
\texttt{2022.11.9-11.11}
学校举行运动会加上艺术节,当然要去玩啦!
老师在班上说,竞赛要学会取舍啥的,怎么感觉在讽刺我捏
\texttt{2022.11.12}
-
P3957 [NOIP2017 普及组] 跳房子 单调队列优化
\texttt{dp} 。 -
Axel and Marston in Bitland
dp[s][op][i][j]表示以op 起始,i \to j 是否存在距离为2^s 的边,然后用bitset压位处理。 -
P4290 [HAOI2008] 玩具取名 区间
\texttt{dp} ,码量比较大,同时需要注意初始化。 -
P3049 [USACO12MAR]Landscaping S 普通线性
\texttt{dp} ,dp[i][j]表示a 的前i 个与b 的前j 个相匹配的最小花费。 -
Name That Tune 期望
\texttt{dp} ,dp[i][j]表示在听完前i 首歌花费j 秒的期望,然后用前缀和进行优化。
晚上打
\texttt{2022.11.13}
学校模拟赛,又一次凉心。
麻麻生日。
\texttt{2022.11.15}
练习一些树上问题,包括贪心,数据结构和
-
Distance to the Path 想了很久的数据结构题,感觉将问题拆分成子树内外进行考虑,是个很妙的做法。写了篇题解。
-
P2279 [HNOI2003]消防局的设立
\texttt{dp} 和贪心均可做,贪心好写一点,从深度大的节点开始,分别考虑每个节点的儿子节点与父节点。 -
P3942 将军令 上一题的加强版,大致依照之前的思路进行贪心即可。
-
P3523 [POI2011] DYN-Dynamite 和前两题相似贪心与
\texttt{dp} 相结合,不过由要使最大值最小可知需要二分。 -
P1084 [NOIP2012 提高组] 疫情控制 好想但不好写的树上贪心,外面还要套个二分。
-
P4281 [AHOI2008]紧急集合 / 聚会 三个点两两求
\texttt{LCA} ,然后去最优值。 -
P4092 [HEOI2016/TJOI2016]树 用树链剖分维护最大值,不过需要分清楚
\texttt{dfs} 的下标和实际的下标。似乎还有一个离线倒序处理的方式,可以少一个\log 。 -
P4211 [LNOI2014]LCA 码量巨大的树链剖分题。离线处理所有询问,按端点排序后,用树链剖分与差分相结合。对于一个
i ,将链1 \to i 均增加一,查询时计算1 \to z 的值即可。 -
Book of Evil 还是子树内外分开考虑的套路,
dp_{u,0/1} 表示以u 为根的子树内怪物与u 的最大/次大距离,dp_{u,2} 表示u 到子树外怪物的最大距离,然后两次\texttt{dfs} 进行转移。 -
Centroids 继续换根
\texttt{dp} ,设dp{u,0/1} 表示以u 为根子树内最大/次大的且不超过\frac{n}{2} 的子树大小,g_u 表示以u 为根的子树外最大的且不超过\frac{n}{2} 的子树大小,然后和上一题差不多按套路转移即可。
\texttt{2022.11.17}
-
Vitaly and Advanced Useless Algorithms 复习了一道关于
0-1 背包的题目,细节有点多调了1h ,顺便水了一篇题解。 -
P5017 [NOIP2018 普及组] 摆渡车 再次写了这题,在题解的提示下用斜率优化写过这题目。
做点图论相关的题,顺便复习了下缩点。
-
P4568 [JLOI2011] 飞行路线 分层图的思想,也就是所谓的拆点。
-
P1462 通往奥格瑞玛的道路 二分后跑最短路,最大费用最小化就很套路。
-
P2783 有机化学之神偶尔会做作弊 边双连通分量缩点后求
\texttt{LCA} ,感觉也很套路,就当复习一下。 -
P1491 集合位置
-
P2865 [USACO06NOV]Roadblocks G 两题均和次短路有关,而下面的允许重复走一条边。因此前者每次删一条边后跑最短路,后者遍历枚举每一条未删的边计算
dis1_u + dis2_v + val_i 的最小值。 -
Too Many Constraints 与 [ABC277Ex] Constrained Sums 都是
\texttt{2-SAT} 的题目,难点都在于将约束条件转换为连边,最后跑tarjan是套路。细节很多,调了整整一天。
官方分数线出了,被卡在
\texttt{2022.11.18}
学一点之前一直没搞懂的期望
-
FAVDICE - Favorite Dice 同 P1291 [SHOI2002] 百事世界杯之旅 再同 优惠券 Coupons 设
f_i 表示已经扔了i 面后,还需仍的次数的期望。则f_i = \dfrac{i}{n} \times f_i + \dfrac{n - i}{n}\times f_{i + 1} ,即f_i = f_{i + 1} + \dfrac{n}{n - i} ,再次转换知f_i = f_{i + 1} + \dfrac{n}{i} 。 -
P4550 收集邮票 和上一题有些相似
f_i = f_{i + 1} + \dfrac{n - i}{i},g_i = \dfrac{i}{n} \times (f_i + g_i + 1) + \dfrac{n - i}{n} \times (f_{i + 1} + g_{i + 1} + 1) = g_{i + 1} + f_{i + 1} + \dfrac{i}{n - i} \times f_i + \dfrac{n}{n - i} ,直接递推求解。 -
P2719 搞笑世界杯
f_{i,j} 表示分别剩下i 与j 张时的票时,最后两张票相同的概率,则在i > 1,j > 1 时均为\frac{1}{2} 的概率转移,注意边界条件的判断。 -
P3802 小魔女帕琪
7 个一组进行分析且互不干扰,所以共有n - 6 组p = (n - 6) \times E(x) = (n - 6) \times \dfrac{7! \times a_1 \times a_2 \times \cdots \times a_7}{n \times (n - 1) \times \cdots \times(n - 6)} ,化简一下直接写就行了。
写一道有关矩阵乘法优化的
- P3176 [HAOI2015]数字串拆分 写了篇题解。
平衡树下周再看一下吧,希望别鸽。
\texttt{2022.11.19}
打洛谷的
第一题容易发现答案为
第二题
第三题,不会,直接写了暴力。
第四题,没啥想法,也是暴力。发现第二个子任务可做,但是觉得有点烦就没写。
最后得分
\texttt{2022.11.20}
校内模拟赛。
信心赛,四道题后来都在洛谷上找到了。
-
P1161 开灯 易知
x \oplus y \oplus y = x ,所以全部异或起来即可。 -
P1174 打砖块
\texttt{50 pts} 的\texttt{dp} 十分好写,dp_{i,j} = dp_{i - 1,j - s} + sum_{i,s} ,处理一个前缀和即可。这题就麻烦在遇到Y时只赚不亏,所以可以“借”子弹然后归还(然而前提是能够借到)。打的时候过了样例,但是测的时候发现还是写错了。 -
P1950 长方形 只要找到不重复统计的方式,然后直接单调栈优化即可(机房好像还有人写出了
\texttt{dp} 做法)。 -
P1462 通往奥格瑞玛的道路 前几天刚做过,直接二分加上最短路。
最后得分,
\texttt{2022.11.23}
考前最后一场模拟赛。
【简要题意】
基于贪心思想的计数
【简要题意】 求
写递推式,map,节省空间与时间。
【简要题意】 给定一个长度为
线段树维护区间两个端点最长同色串的类型与长度,区间两个端点最长
【简要题意】 构造数列
没想法,写了暴力。赛后看了题解还是不会,只知道是数学推式子题。
最后得分,
\texttt{2022.11.24}
做做
-
P7114 [NOIP2020] 字符串匹配 预处理前后缀出现奇数次的字符数量,然后枚举
AB ,由于只有26 个字母,在判断C 时直接用树状数组求出符合条件的A 的个数,枚举AB 出现的次数采用了哈希。最后发现开O2 才能过,由于现在比赛自开O2 ,所以就没事了。 -
P6739 [BalticOI 2014 Day1] Three Friends 哈希判重,唯一的坑点就是多解是指得到的
S 不唯一而不是方式不唯一(可能多种方式均得到同一个S )。 -
P3538 [POI2012]OKR-A Horrible Poem 若
f(l,r - len) = f(l + len,r) ,则len 为一个可能的循环节,所以线性筛预处理每个数对应的最小素因子即可。
总结一下哈希(
- 从
s 中截取s[l:r] ,哈希值为hsh_r - hsh_{l-1} \times pw_{r - l + 1} 。 - 将
1. 的计算方式编写为函数f(x,y) ,将s 中的s[sx:sy] 与s[fx:fy] 合并,哈希值为f (sx,sy) \times pw_{fy - fx + 1} + f (fx,fy) 。 - 不要忘记
pw_0 = 1 的初始化。
\texttt{2022.11.25}
练习骗分/调试小技巧。
- 打表 洛谷日报《浅谈打表与其技巧》。【注意
\texttt{CCF} 的代码长度上限是100KB 】
具有一般性的,通过分块打表来缩减表长,将搜索与表相结合,从而优化代码。
-
P2567 [SCOI2010]幸运数字 搜索出幸运数只有
2000 个左右,因此可以通过这些幸运数进行打表,块长设置在2 \times 10^6 较为合适。 -
P4318 完全平方数
5 \times 10^5 的表长加O2 终于过了。如果想要不吸氧并且在合理长度内,可以将表同减某一个数以缩小长度,最后加上即可。
- 对拍
防止 .bat 文件出错,写成在 Dev-C++ 内的形式。
#include<windows.h>
using namespace std;
int main(){
while(1){
system("data.exe");
system("bf.exe");
system("sol.exe");
if (system("fc bf.out sol.out")) break;
}
}
-
模拟退火 重做了 P1433 吃奶酪 不过只拿到一半的分,不管了,会这个方法就行。
-
clock () - st < 0.9 * CLOCKS_PER_SEC卡时,注意前面单位是 毫秒,后面是秒。 -
应试技巧 看了看这篇博客。
好了,写完了,明天比赛加油吧!
\texttt{2022.11.26}
要去打