title: 2026暑期提高模拟卷 - 01
tags: []
categories: [OI, 模拟赛复盘]
\(165/400\)
CF1519D Maximum Sum of Products \(100/100\) 区间DP
P3076 USACO13FEB Taxi G \(10/100\) 贪心
失分原因:贪心策略没想到,没有构建到题目的思路上。
魔法药水 \(45/100\)
密文 \(10/100\)
教训:多做贪心题,多打暴力分
official题解
T1:
题意:给定一个序列 \(a_i\),序列 \(b_i\),可以翻转 \(a_i\) 的一段区间,求 \(\sum{a_ib_i}\) 最大值 \(n\le 5000\)。
直接枚举翻转的两端点的话,每次都要重新扫描一遍,浪费了。
翻转这个操作,一般可以抓住对称中心来做。
这个题可以直接枚举中心,往两端拓展,这样前面求出的信息就可以重复使用了。
注意分长度为偶数和长度为奇数讨论(对称中心在两个数之间/中心是一个数)
由于 \(n\le 5000\),可以通过,不过也存在一些 dp 做法。
难度:黄
T2:
感觉需要一定巧思的题目,如果直接考虑dp整个过程怎么走就偏离正解了。
首先送外卖的这些路程我们省不了,这部分代价是 \(\sum |a_i-b_i|\),只能减小额外跑动(也就是不运送外卖)的路程。
应该如何最小化这个路程?‘
考虑在什么地方我们会在终点之前丢下手中的外卖,发现放下地方必然有其他外卖可以拿,也就是其他外卖的起点。(而这种情况下手里还拿着外卖不会产生额外跑动)。
当放下一份外卖 \(i\) 的时候,我们发现这一份外卖和此处的那一份外卖 \(j\) 并没有本质区别,可以将终点\(b_i,b_j\)互换,这样外卖 \(i\) 就变成从 \(a_i\to b_j\) 外卖 \(j\) 就变成从 \(a_j\to b_i\),可以省去这次放下的过程。
现在问题变为将 \(a_i,b_i\) 重排,最小化所有从终点到起点的路程和。也就是重排形成形成 \(a'_i,b'_i\) 并最小化 \(\sum|b'_i-a'_i|\)。
直接将 \(a_i,b_i\) 从小到大排序之后依次配对就可以了,注意由于要求从 \(0\) 最终走到 \(L\),可以令 \(a_0=m,b_0=0\) 放到一起排序。
为什么这样配对是最小的假设能够交换两个位置 \(i,j,i<j\)
考虑\(|b_i'-a'_i|\),\(|b'_j-a'_j|\)
若 \(b_i'>a'_j\) 或者 \(b'_j<a'_i\),交换无影响,贡献均为 \(b'_i+b'_j-a'_i-a'_j\)。
否则若 \(a'_i<b'_i<b'_j<a'_j\),那么交换后贡献从 \(a'_j-a'_i-(b'_j-b'_i)\) 变成了 \(a'_j+b'_j-a'_i-b'_i\),不优。
若 \(a'_i<b'_i<a'_j<b'_j\) 同样得到交换后贡献从 \(b'_j-a;_j+b'_i-a;_i\) 变成了 \(b'_j-a'_i+a'_j-b;_i\) 不优
其他情况也是类似的。
难度:青,洛谷P3076
T3:
最小值最大,想到二分魔力值 \(d\)。
二分之后只考虑 \(\ge d\) 的材料,由于要价格低的情况下体积还要大,所以可以直接贪心地取单价 \(p_i\) 比较低的材料,直到取满 \(L_i\)。
如果对于每个询问都这么做,时间复杂度应该是 \(O(nm\log d)\)的。
为了快速统计,需要使用数据结构优化。
按照材料从大到小排序,对于每个材料建立一个版本的线段树,并且以价格为下标,每个节点存储该价格区间的总库存和总花费。
查询时,在对应版本的线段树上进行线段树上二分:若左子树库存足够,则走左边;否则买下左边全部,再去右子树寻找剩余体积。
难度:紫
T4:
考虑每个位置上被哪一个条件“约束”
先不管离散化什么的,这个对于本题最终解法影响不大,只是明显加大了代码和处理上的难度。
对于一个位置,这个位置填数的范围被包含它,且x最小的那个的那条限制约束,
因为填了小的数, \(\le\) 更大的 \(x'\) 的要求就自动满足了,除非让更大的 \(x'\) 没地方填了,这个时候注意判断无解。
特别地对于没有任何限制的那些位置,显然可以再 \(1\sim k\) 之间随便填写
这样,每个位置i事实上只受一个 \(x\) 值的影响,(但是可能会存在多个包含\(i\),且限制为 \(x\) 的区间,而这正是本题终点需要处理的)
于是我们可以对于每个不同的 \(x\) 值分开做,而且只考虑那些受到x限制的位置,将其他位置剔除。最后对于不同的 \(x\),将答案乘起来。
现在问题转化为长度为 \(n'\) 的区间可以填写 $1\sim x $ 中的数,且给定若干条限制\([l,r]\),要求 \([l,r]\) 之间至少填过一个 \(x\)
可以设计dp \(f_{i,j}\) 表示考虑到位置 i,上一个填写x的位置是 j 的方案数,
这个 dp 怎么转移呢
首先处理出一个辅助数组 \(lst_i\) 表示如果上一次是在 i 填写了 x,那么最晚到什么位置一定要填写 x。
这个可以通过扫描一遍所有限制进行处理:
从大到小枚举 i,然后看看有没有左端点 \(l=i+1\) 的限制,如果有,那么设 \(r_{min}\) 为所有区间中最小的右端点位置,那么就让 \(lst_i=\min(lst_{i+1},r)\)
转移的时候可以分当前这位填/不填 x,如果填,那么 \(f_{i+1,i}+=f_{i,j}\)
否则 \(f_{i+1,j}+=f_{i,j}*(x-1)\),但是若 \(i+1>lst_j\) 就不可以转移(超出了最晚填写的额位置,不满足题意)
这样复杂度大概是 \(O(nm)\) 的,虽然看似有三重循环,但是其实 \(\sum n' =n\) 复杂度是对的,离散化以后可以让 \(\sum n' =O(m)\) 做到 \(O(m^2)\)得到满分。
离散化之后,原来的一个位置就变成了一段长度为 len 的区间,转移的时候需要改一下
\(f_{i+1,i}+=f_{i,j}*(x^{len}-(x-1)^{len})\) 容斥:表示这段区间里面填了至少一个x
\(f_{i+1,j}+=f_{i,j}*(x-1)^{len}\) 表示只能填写 \(< x\) 的数
然而进一步地,这些操作可以使用线段树维护,需要支持区间乘法,单点改,区间和(详见ABC262Ex)做到 \(O(m\log m)\)。
难度:紫,洛谷P4229/ 加强版:ABC262Ex,atcoder rating *3000
浙公网安备 33010602011771号