0907训练

P - windy 数

首先考虑把 \([a,b]\) 的答案转化为 \([1,b]\) 的答案减去 \([1,a-1]\) 的答案。

然后就可以数位 \(dp\),设 \(dp_{i,j,k}\) 表示当前 \(dp\) 到第 \(i\) 位,上一个是 \(j\),目前是否已经小于目标的方案数。

这个题有一个不同之处是前导 \(0\) 不能当存在,所以需要从最高位开始插入。

Q - 超级钢琴

考虑二分答案我们选择的权值最小的区间是多小。

我们对当前 \(check\) 的答案 \(x\),考虑对每个右端点,找到它左端点可行的选择区间 \([i-R+1,i-L+1]\),有多少个位置满足 \(s_r-s_{l-1}\ge x\)

这个显然可以主席树,但是也可以离线之后树状数组解决。

然后,我们处理出所有 \(>x\) 的区间和,并统计这样的区间有多少个,不足 \(k\) 则直接用 \(x\) 补齐。

具体的,我们用 set 存储所有可行的左端点,然后将所有符合条件的弹出贡献,再压回去。因为我们的可行区间是连续的,且左右端点都单调,弹出次数不会超过 \(k\),所以复杂的有保证。

最终复杂度 \(O(n\log ^2n)\)

R - 摆渡车

\(dp_{i}\) 表示 \(t_i\) 时刻出发了一辆车,\([1,i]\) 之间的所有人的等待时间总和。

我们发现发车时间其实只有两种:

  • 上一次车回来立马发车

  • 在某个人来了立马发车

剩下的所有情况,都可以找到最近的如是的关键点,平移过去,一定会更优。

所以,我们考虑每次从 \(t_i\) 发车之后,跟了若干次上次车回来立马发车,直到 \(x\) 的前一次不发车,等到 \(t_x\) 再发车。

然后考虑 \([i+1,x]\) 内的贡献,就是一个 \(m\) 的循环周期,每个人找到所在周期的右端点,进行贡献即可,然后就是 \(dp_i\) 转移到 \(dp_x\)

复杂度 \(O(n^3)\)

S - 序列分割

首先,划分序列的顺序和答案无关,即存在结合律。

直接暴力验证,\(a(bc)=ab+ac+bc,(ab)c=ac+bc+ac\)

所以我们直接暴力枚举切割点,设 \(dp_{i,j}\) 表示前 \(i\) 个字符分了 \(j\) 段的最小答案。

那么 \(dp_{i,j}=\min \{dp_{x,j-1}+(s_i-s_{x})s_x\}\)

发现 \(s_i\) 单调,显然可以斜率优化。

结束了,复杂度 \(O(n)\)

T - 可重集

关键是哈希函数的挑选。

首先考虑找到 \(k\),这个很简单,我们找到两段区间的区间最大值,他们的差就是 \(k\)

然后考虑哈希,哈希函数要满足区间加性质,还要很方便的集体平移 \(k\)

我一开始用线段树维护平方和,利用 \((a_i+k)^2=a_i^2+2a_ik+k^2\) 平移,但是冲突了。后来改成立方和,依旧冲突了。

考虑什么样的哈希函数可以平移,还有不错的随机性。

我们发现,如果随机一个值 \(x\),那么设哈希函数为 \(x^a\)\(\sum x^{a+k}=x^k\sum x^a\),有很好的平移性。取模之后几乎就是随机值了,有不错的随机性。

那就很好了,线段树维护单点修改、区间和、区间最值。

感觉非常智慧。

U - Corn Fields

考虑轮廓线 \(dp\)\(dp_{x,y,msk}\) 表示当前处理到 \((x,y)\),轮廓线上的草坪情况是 \(msk\),那么当且仅当原先 \(y-1\)\(y\) 都是空的且 \(a_{x,y}=1\),才能在 \(y\) 上填。

就做完了

复杂度 \(O(nm2^m)\)

posted @ 2023-09-07 21:58  jucason_xu  阅读(13)  评论(0编辑  收藏  举报