解题报告—9.21
T1 相遇
反思
T1 考到了 LCA,之前觉得没必要学,虽然也看过些文章,但大部分都没看懂,所以一直都不会,结果今天出上了这样的一道题,真尴尬,想着写写暴力吧,发现暴力也是求 LCA,无奈,遂放弃,考完试的下午就开始学 LCA,以后有能力学的东西尽量学学,不能老想着偷懒。
解题思路
画几个图会发现 a→b,c→d 两条路径如果能够相交的话,需要满足其中一对点的 LCA 在另两个点之间的路径上。
而一个点 x 在一条路径 s→t 上的充要条件是如下:
- depth[LCA(s,t)]≤depth[x]
- LCA(x,s)=x || LCA(x,t)=x
然后我们就可以做 LCA 进行求解,一组数据最多询问 4 次。
代码
1 |
|
T2 计数
反思
不开 long long
见祖宗,写了个 60 分的暴力,因为没开 long long
所以 WA 成了 30 分,以后做题先看好数据范围,可以为了以防万一,能开 long long
就开 long long
。
解题思路
在考场上写了个线段树维护区间最大最小值。然后 N2 枚举,左右端点,求和。算上查询的时间是 logN 总时间复杂度为 N2logN 可以过 60 分。
再说正解:
题目大意可以简化为求下面这个式子的值:
n∑r=1r∑l=1max(a[x]−a[y],l≤x,y≤r)
观察上面的式子,其实可以从 1→n 算出每个数对答案的影响,相加就是答案。
那么怎么算贡献呢。用单调栈维护,一个点被弹出后就将其贡献减去,被压入后,就将其贡献加上。
求作为最大值的贡献和求作为最小值的贡献其实差不多,求最小值时将数组变成负数就又变成了求最大值的问题。
所以可以用一个函数解决。
代码
60 分
1 |
|
100 分
1 |
|