2025HZ暑集做题记录(Part.2)
没有Part.1
2025.7.15-2025.8.3HZ暑集做题记录 &唐氏集锦 (对应集训游记\(Part.2\))
线段树合并 7.15-7.16
1.普通平衡树
权值线段树板子题
可以用动态开点线段树在线处理,也可以离散化后用普通线段树离线处理
2.永无乡
用并查集维护连通性即可
3.雨天的尾巴
第四题才到线段树合并板子题
依然是用权值线段树维护各个种类物品的个数
用到了树上差分:
对于树上两点\(x , y\),设其\(LCA\)为\(l\),\(l\)的父节点为\(l'\)(若存在)
可将\(x\)到\(y\)的树链修改转化为\(x,y\)单点修改(增加),\(l,l'\)单点修改(减少);将单点查询转化为子树和查询
\(15pts\)->\(70pts\)->\(100pts\):一次修改至多修改\(4\)个节点,因此线段树在空间复杂度为\(O(n \log n)\)的基础上还有\(4\)倍常数,对应到代码中即为M << 6
4.韶身的数列
注意到序列某个位置的值为对该位置有影响的所有修改的\(k\)的最大值
即:$ m_i=\max_{1 \leq j \leq N,a_j \leq i \leq b_j} k_j$
那么操作顺序不会对\(N\)次操作后的最终结果造成影响
不妨对所有操作以\(k\)为关键字升序排序,则在此顺序下每次操作都会改变所有范围内的序列元素(\(m_i=k\)时虽然值不会有实质性的改变,但也可视作由\(k\)改变至\(k\))
用动态开点线段树维护区间和,区间覆盖即可
5.天天爱跑步
不妨钦定节点\(1\)为根节点
设节点\(x\)的深度为\(dep_x\),时间为\(t\)
注意到如下性质:当玩家沿叶子结点到根节点的方向运动时,\(dep_x+t\)的值不变;当玩家沿根结点到叶子节点的方向运动时,\(dep_x-t\)的值不变
我们可以记录玩家以及观测员的\(dep_x+t\)、\(dep_x-t\)的值,用线段树合并分别处理
只需将\(x\)到\(y\)的路径转化为\(x\)到\(l\)的路径与\(y\)到\(l\)的路径,再除去重复计算的\(l\)即可
6.魔法少女LJJ
难绷题目,题干中有九种操作但数据范围中操作编号为\(1\) ~ \(7\)
bro差点以为要用\(LCT\)
连通块用并查集维护,合并连通块时将被合并的连通块大小加到合并至的连通块大小上
第六种操作中直接维护节点权值之积较为困难,可维护各节点权值之积的对数,运用\(\log_a{mn} = \log_a{m} +\log_a{n}\)实现增加节点和权值修改,比较时直接比较积的对数
\(0pts\) ->\(100pts\):已经处于同一连通块的两个节点加边时不能合并根节点,否则同一个节点会和它自身进行合并
笑点解析:写永无乡的时候注意到这个问题了,结果写这个题时没发现
7.大融合
我还是不知道这个题放在线段树合并专题的用意是什么,反正我用并查集+树链剖分+树状数组就解决掉了
依然是离线算法,先将所有操作存起来,对所有加边操作都加上这些边,建出最终的树,然后对每棵树进行树链剖分
接下来就到了精华部分:询问的“负载”其实就是这条边将其所在连通块分成的两个部分的节点数的乘积,而每条边连接的又必定是一个父节点(设为\(x\))和一个子节点(设为\(y\),设其子树大小为\(s_1\)),设节点\(x\)所在连通块的深度最小的节点的子树大小(即\(x\)所在连通块大小)为\(s_2\),则询问的实际上就是\(s_1(s_2-s_1)\)
因此我们只需动态维护子树大小即可
加边时设每条边连接的父节点是\(x\),子节点是\(y\),节点\(y\)子树大小为\(s_1\)
则子树大小发生改变的只有\(x\)及其祖先,这其实是一条树链,故可以在树剖得到的\(dfs\)序上进行区间修改
询问子树大小时可在\(dfs\)序上进行单点查询
用树状数组维护即可
\(10pts\)->\(100pts\):树剖写挂了(最开始以为是写的线段树挂了,然后改成树状数组还是挂,后来才发现是树剖写挂了)
8.基站选址
贺的题解,感觉没什么必要写,还不如找一篇题解放上来
\(0pts\)->\(100pts\):基站个数不超过\(k\),\(k\)的各个取值均可更新答案
2025.7.16 20:00~21:00
容斥原理,二项式反演,min-max容斥 7.17
没有。
写了一半结果电脑死机了,写的东西没存,一怒之下决定断更一天
2025.7.17 21:00~21:30
可持久化数据结构 7.18
有点难调……一天没做几个题
1.七彩树
贺的题解
不妨将深度作为主席树的版本
每次查询时只需查询深度为\(depth_x+d\)所对应的版本中\(x\)的子树中颜色个数即可
添加节点时则按节点深度递增顺序添加至对应的版本中
接下来考虑如何计算颜色个数
新增一个节点\(x\)时,可将其\(dfs\)序对应的颜色数加一
但是,若某节点的子树中有多个同一颜色的节点,统计子树和时就会造成重复统计
考虑与\(x\)同色的节点中\(x\)的\(dfs\)序的前驱\(prev\)、后继\(next\)(若存在)
则\(lca(x , prev)\)及其祖先统计的颜色数都多了\(1\),减去即可;\(next\)同理
但\(lca(prev , next)\)被减了\(2\),故应再加上\(1\)
前驱、后继用set维护即可
2.[HEOI2013]ALO
考虑枚举每个值何时成为次大值以及成为次大值时\(l,r\)可延伸至何处
对于\(a_i\),设在其左侧首个大于\(a_i\)的值的下标为\(l_{i1}\),左侧第二个大于\(a_i\)的值的下标为\(l_{i2}\);在其右侧首个大于\(a_i\)的值的下标为\(r_{i1}\),右侧第二个大于\(a_i\)的值的下标为\(r_{i2}\)(若存在)
若\(l_{i1}\)成为最大值,则最长段为\((l_{i2},r_{i1})\);若\(r_{i1}\)成为最大值,则最长段为\((r_{i2},l_{i1})\)
两个区间取并,则有最长段为\((l_{i2},r_{i2})\)
区间异或最大值可使用可持久化\(Trie\)求解
若\(l_{i2}\)不存在,则将其设为\(0\);若\(r_{i2}\)不存在,则将其设为\(n+1\)
注意:整个序列的最大值不可能成为次大值,需特判
3.最大异或和
可持久化\(Trie\)板子
把会改变的后缀异或和转化为整个数组的异或和异或上不变的前缀异或和
4.Fotile 模拟赛 L
人类智慧魅力时刻
数据结构、动态规划,能AC就是好算法
正解貌似是分块\(+\)可持久化\(Trie\)
但是正解死活打不出来,花了两个小时时间在没写出来的正解上
一怒之下决定使用\(dp\)
设\(dp_{i,j}\)表示区间\([i,i+j]\)中的最大异或和,\(f_{i,j}\)表示区间\([i,i+j]\)所有数的异或和,则有\(dp_{i,j}=\max{(dp_{i+1,j-1},dp_{i,j-1},f_{i,j})}\)
\(f_{i,j}\)可用前缀异或和在\(O(1)\)内求出,整个\(dp\)过程是\(O(n^2)\)的,回答询问为\(O(m)\),能够在正确的时间内求出结果
这下能轻松AC了!…………吗?
一个\(12000\times12000\)的int数组占用内存约\(550\) MB,超出了洛谷的\(512\) MB空间限制……会RE
这时注意力惊人的我们注意到:\(dp\)数组只有一半的空间被占用,剩余一半满足\(i+j>n\),是无效的,那么我们可以使用vector优化掉多余空间,只需占用\(275\) MB内存
这下又能轻松AC了!…………吗?
优化后的数组占用内存约\(275\) MB,超出了hszxoj的\(256\) MB空间限制……会RE
这时注意力惊人的我们注意到:我们可以只存储\(dp\)数组中\(j\)为\(3\)的倍数的情况,查询时查询最大的长度为\(3\)的区间内最大异或和,超出可查询最大长度的直接暴力处理
这样就将内存减小到了\(1/3\),也就是\(183\) MB
这下能轻松AC了!
2025.7.18 21:35~22:10
自主补题 7.20
各个专题的题都补了补,所以比较乱
1.可持久化并查集
板子题
用主席树维护某一版本中各节点的\(fa\)值,查询时与普通并查集相同,不断跳\(fa\)直到\(fa_x=x\)
使用启发式合并可保证每次跳\(fa\)子树大小至少增大一倍,从而保证跳\(fa\)次数在\(O(\log n)\)水平
2.[NOI Online #2 提高组] 游戏
贺的题解
树上背包\(+\)二项式反演
设\(f_{u,x}\)表示在\(u\)子树中非平局次数至少为\(x\)的方案数
则对于\(u\)的每个子节点\(v\)都需要进行\(f_{u,i+j}=f_{u,i+j}+f_{u,i} \times f_{v,j}\)的\(dp\)转移
整棵树中非平局次数为\(k\)的方案数\(F_k\)为\(f_{1,k}\)乘以剩余\(n/2-k\)对节点任意组合的方案数\((n/2-k)!\),即\(F_k=f_{1,k} \times (n/2-k)!\)
已知至少求恰好,使用二项式反演即可
3.[PKUWC2018] 随机游走
蒟蒻独立AC的第一道黑题qwq
不会用LATEX,打不出来子集的符号,凑合看吧qwq
min-max容斥\(+\)图上随机游走\(+\)高斯消元
据说这题正解为\(O(n 2^n)\),但是我的\(O(n^3 2^n)\)做法凭借神秘优化和小常数成功AC
令到达点\(u\)所需期望步数为\(E(f_u)\),则经过\(S\)中每一个点的期望步数为\(E(\max_{i \in S} f_i)\)
由min-max容斥可得:\(E(\max_{i \in S} f_i)= \sum_{T \subset S} (-1)^{|T|-1} E(\min_{i \in T} f_i)\)
因此我们只需求\(E(\min_{i \in T} f_i)\),即由点\(x\)出发到达某个\(S\)中的节点的期望步数
设\(E\)为边集,\(deg_i\)为节点\(i\)的度,\(g_i\)为节点\(i\)到达\(T\)中的节点的期望步数
不妨使用图上随机游走构造方程组:
当\(i \in T\)时,\(g_i=0\)
当\(i \notin T\)时,\(g_i=1 + \sum_{(i,j)\in E} g_j / deg_i\)
使用高斯消元求解,解得\(g_x\)即为所求的\(E(\min_{i \in T} f_i)\)
此时,单次查询需要查询每个\(S\)的子集,复杂度仍然太劣
不妨对每个节点都作为一维求高维前缀和,即可实现\(O(1)\)回答询问
枚举\(T\)的复杂度为\(O(2^n)\),高斯消元复杂度为\(O(n^3)\),故复杂度为\(O(n^3 2^n)\)
求前缀和复杂度为\(O(n 2^n)\)
回答询问复杂度为\(O(Q)\)
竞选全网最难绷做法
4.[THUPC 2023 初赛] 背包
还是贺的题解
同余最短路,但貌似又不只是同余最短路
需要以\(c_i/v_i\)最大作为基准物品,设其体积为\(m\),价值为\(w\)
转移时状态应设为\(f_i\)表示已选物品体积模\(m\)为\(i\),除去已选体积包含的\(m\)的倍数所对应的\(w\)后的代价
对于物品\(p\),令\(q\)为\((i+v_p)/m\)向下取整的结果其实是因为不会LATEX,则
\(f_{(i+v_p) \mod m} = \max(f_{(i+v_p)\mod m},f_i+c_p-wq)\)
可以跑最短路,也可以对每一个模\(\gcd(v_p,m)\)的剩余系进行两轮环状递推
5.[模板]可持久化平衡树
板子题
你怎么知道我其他部分一遍写真,结果删除节点假完了
6.[APIO2018] 铁人两项
圆方树
对于一个点双中的两点,它们之间简单路径的并集,恰好完全等于这个点双。
将所有圆点赋值\(-1\),方点赋值为它的度,则\(s,f\)间符合题意的\(c\)个数恰为圆方树上这两个点路径的点权和(圆方树路径上的点双的每个节点都可被统计,故方点赋值为它的度;割点、起点、终点均被多统计了一次,故圆点赋值为\(-1\))
题目要求求所有路径点权和总和,无法通过\(LCA\)求解,不妨转化为每个点出现次数与点权之积的总和,即可通过树形\(dp\)求解
注意:被统计的路径两端均为圆点,方点不参与子树圆点个数的统计
2025.7.20 20:40-21:50
杂题1 7.22
是hzoi2024A层学长找的题qwq
学长找题的时候问我们能做什么难度的题,我们回答上位蓝/下位紫,学长遂在题单中放了两道黑题
都是好题啊
1.[JOISC 2023 Day4] Bitaro's Travel
最开始想写\(O(n^2)\)的暴力,觉得肯定会\(TLE\)就没写
转而写了记忆化搜索,结果还是\(TLE15pts\)
于是开始写正解
我们注意到:任一情况中已达的节点编号必定为一连续段,且当前所在的节点必定是连续段的两个端点之一
那么不妨已访问的连续段为\([u,v]\)
当当前正在节点\(u\)时:
要么向右走到\(v+1\)节点,经过\(x_{v+1}-x_u\)的路程;
要么一直向左走到节点\(p\),即$p = \min_{1\leq q < u,x_u-x_q \leq x_{v+1}-x_u} q \(,经过\)x_u-x_q$
节点\(p\)可直接用lower_bound查询
当当前正在节点\(v\)时情况类似
注意到每次查询区间长度都会接近指数增长,可认为一次查询的时间复杂度为\(O(\log n)\)
2.[Cnoi2020] 领域极限
没有严格证明,全是感性理解
题意要求求任意两点距离和的最小值,我们不妨令所有数尽可能接近,即:取某一个数\(p\),令\(a_1,a_2, \dots ,a_n\)尽可能接近\(p\)(\(r_i < p\)时取\(a_i=r_i\),\(l_i > p\)时取\(a_i=l_i\),否则取\(a_i=p\)),则最优情况便出自于这些情况中,我们只需枚举\(p\),对于每一个\(p\)都求一次答案即可
于是,我们就有了复杂度为……\(O(n^2 V)\)的算法
复杂度也太劣了啊喂
为了下文叙述方便,我们先规定\(r_i < p\)的点为“一类点”,个数为\(f_1\);\(l_i \leq p \leq r_i\)的点为“二类点”,个数为\(f_2\);\(l_i > p\)的点为“三类点”,个数为\(f_3\)
其实我们不必对于每个\(p\)都对每组\(1 \leq i \leq n,1 \leq j \leq n\)都一个一个统计答案
我们考虑在\(p\)移动至\(p+1\)时答案的增量
移动\(p\)时只有二类点的位置会发生改变,故只需统计二类点对所有点的贡献,适时更新\(f_1,f_2,f_3\)的值即可
- 二类点与一类点:每个二类点与每个一类点都会远离\(1\)单位长度,答案加\(f_1 f_2\)
- 二类点与二类点:所有二类点都在同一位置,答案不变
- 二类点与三类点:每个二类点与每个三类点都会靠近\(1\)单位长度,答案减\(f_1 f_3\)
故答案会增加\(2f_2(f_1-f_3)\)(\(2\)来自于每个点对会计算两次贡献)
于是我们就有了\(O(V)\)的递推,\(O(n^2)\)的预处理
我们又注意到:将所有区间端点按位置从小到大排序,在相邻两个端点间,答案的增量不变,则答案在该段内为一次函数,利用我们在二年级学到的知识可以得出,区间内极值必定在区间端点处取得,则我们只需枚举所有端点,转移时加上\(2f_2(f_1-f_3)(x_j-x_i)\)即可
于是我们只需要\(O(n \log n)\)对端点排序,\(O(n)\)遍历端点即可
而\(O(n^2)\)的预处理我们也可以优化,显然,我们要预处理出\(p=0\)时式子的值,即\(\sum_{i=1}^{n}\sum_{j=1}^{n} |l_j-l_i|\)
我们考虑将所有\(|l_j-l_i|\)分成小段计算,即:将\(l\)排序,则排序后\(l_{i+1}-l_i\)被经过的次数即为两侧端点个数之积的二倍,则答案为\(\sum_{i=1}^{n-1} 2i(n-i-1)(l_{i+1}-l_i)\)
这下便做到了严格O(n \log n)复杂度
2025.7.24坏了我昨天写的做题记录没保存
2025.7.25&26颓
2025.7.26被abc薄纱
manacher 后缀数组 后缀自动机 回文自动机 2025.7.27-2025.7.28(Part.1)
APJ学长来给我们讲课了!!!!!
1.【模板】后缀排序
板子
你怎么知道我的\(O(n \log^2n)\)能过
2.[JSOI2007]字符加密Cipher
复制一遍再进行后缀排序即可
3.不同子串个数
子串总数\(\frac{n(n+1)}{2}\)
重复子串贡献$\sum_{i=1}^{n} \operatorname{height}(i) $
4.[Poi2000]公共串
首先将所有字符串连接起来,相邻字符串以分隔符如#分隔
求出height数组后双指针维护每个字符串子串都包含在内的连续段,单调队列维护区间最小值即可
5.[Usaco2006 Dec]Milk Patterns 产奶的模式
求出height数组后用单调队列维护任意连续\(k-1\)个height值的最小值的最大值
6.[AHOI2013] 差异
原式可拆成两部分,即
前半部分,对于每个长度,其必定在作为\(j\)时被所有\(i\)统计,在作为\(i\)时被所有\(j\)统计,即被除自身以外的所有位置统计一次,共\(n-1\)次,故
后半部分相当于在height数组上求任意区间的最小值之和,可转化为任意一个位置作为最小值的方案数与该位置的值之积的和,作为最小值向左、向右扩展的长度可用单调栈求出,则
7.【模板】manacher
板子
8.[Poi2010] Antisymmetry
不难发现仅当合法子串左右两侧字符不同时才可进行扩展
把板子中==换成!=即可
注意:该题中合法子串的长度必定为偶数
9.[国家集训队] 拉拉队排练
求出最长合法回文子串长度\(l_i\)后将\(x \in [1,l_i]\)的所有\(cnt_x\)全部自增\(1\)
可用树状数组维护
注意:该题中合法子串的长度必定为奇数
2025.7.27 21:10~21:45
咕咕咕

浙公网安备 33010602011771号