【GDOI2005】山海经题解
Description
《山海经》是以山为纲,以海为线记载古代的河流、植物、动物及矿产等情况,而且每一条记录路线都不会有重复的山出现。某天,你的地里老师想重游《山海经》中的路线,为了简化问题,老师已经把每座山用一个整数表示他对该山的喜恶程度,他想知道第a座山到第b座山的中间某段路(I,j),使得他感到是最满意的,即(I,j)这条路上所有山的喜恶程度之和是所有(c,d)(a<=c<=d<=b)最大。于是老师便向你请教,你能帮助他吗?值得注意的是,在《山海经》中,第i座山只能到达第i+1座山。
Input
输入第一行是两个数n,m,2<=n<=100000,1<=m<=100000,n表示一共有n座山,m表示老师想查询的数目。
第二行是n个整数,代表n座山的喜恶度,绝对值均小于10000。
以下m行每行有两个数,a,b,1<=a<=b<=n,表示第a座山到第b座山。
Output
一共有m行,每行有三个数I,j,s,表示从第i座山到第j座山总的喜恶度为s。显然,对于每个查询,有a<=i<=j<=b,如果有多组解,则输出i最少的,如果i也相等,则输出j最少的解。
Sample Input
1 | 5 3 |
Sample Output
1 | 1 1 5 |
Solution
简化一下题目,给定你一个区间,请你求出区间最大子段和
这道题可以用线段树来做。
难点主要在于维护(即pushup)
对于一个子段和,我们分情况来进行讨论
讨论之前,先定义几个东西(封装成一个结构体不然会很乱!)
表示区间最大子段和,表示子段和左端点,表示子段和右端点
表示区间最大前缀和,表示前缀和右端点,(显然左端点为区间左端点)
表示区间最大后缀和,表示前缀和左端点,(显然右端点为区间右端点)
表示区间和
再定义为左儿子,为右儿子
开始分类讨论(讨论过程中同步更新端点(,,,)按照题目要求的优先值)。
(可以自己画图,感性理解一下)
对于,它有2种情况
对于,它有2种情况
对于,它有3种情况
在pushup中小心地讨论即可
Code
1 | // #pragma GCC optimize(3,"Ofast","inline") |