考试总结 模拟$104$

考试过程

感觉这套题的T1T2都很可做

所以这次就趁机对做题顺序稍作改变,前1h比较高效地思考,

T1先想到了一个$msqrt{N}$的分块做法,总觉得是个二分,然后就想到了一个$n log^{2}_{n}$的做法

大概算了一下可能会被卡,但又想不出更好的,

T2想了会部分分但是不太确定,T3概率觉得很不好打,就弃了,

于是就开始打T1,打着就发现了很多细节考虑不到,等打完之后发现只剩1h了

没过样例,只好先写T2暴力,然而发现过不了第三个样例,更加绝望,看了半天觉得dp没错,只好先放着回去调T1

最后没有调出来啊。。。本来以为这次可以翻身。

自己代码能力太弱了啊!!如果觉得很难实现的东西,可以先停一下看看有没有更简单的实现方式。

T2暴力写跪了!!有负数情况下取最大值一定要初始化-INF

题解

T1「递归」

本来想写二分,但是码力太弱了,就写了题解第二种

我们考虑这样一种情况,在a,b两个单调序列中选出前k个数

那么我们只需要去看a,b的第k/2个的大小,若$a_{mid}<b_{mid}$那么说明前a的前mid个一定在最终结果里

那么在剩下的区间中继续递归下去解决子问题,k每次减半复杂度log

注意边界:k==1,l1>r1,  l2>r2, 

特殊处理l1+mid>r1,l2+mid>r2的情况

T2「线段树优化DP」「单调栈」

 定义f[i]表示考虑到i,在i处有断点,的最大贡献

然后枚举j [0,i-1]转移时+cal(min)

那么就可以用线段树维护dp最大值,那么cal(min)呢?

可以发现,在一个点扫过去之后,某个点作为最小值所覆盖的区间是不变的,所以就可以接着用线段树维护了,

每次扫完这个点之后,把这个点往前能覆盖到的区间[l-1,r-1]进行区间覆值,

然后再维护一个mx就好

注意每次pushup的时候 t[k].mx=t[lc].mx+t[rc].mx 

在对dp值或cal值进行了赋值操作后直接 t[k].mx=t[k].dp+t[k].cal 

当然dp值也是pushup

原文地址:https://www.cnblogs.com/casun547/p/11814349.html