原题地址:https://www.spoj.com/problems/GSS2/
题意:询问任意区间内,最大连续序列和(相等的值不重复计算),可以不选输出0;
这题可以说一眼看出是线段树了,可是怎么构造确实非常难. 现在假设线段树中的叶子为 s[i]. 每次更新 a[i]的时候,s[1] -s[i]区间内加上a[i];那么
s[1] = a[1] + a[2] + a[3] + ... + a[i];
s[2] = a[2] + a[3] + ... + a[i];
s[3] = a[3] + ... + a[i];
s[i] = a[i];
变形一下就是所求
ss[1] = max( a[1] + a[2] + ... + a[k1] ) ( k1 <= i );
ss[2] = max( a[2] + a[3] + ...+ a[k2] ) ( k2 <= i );
我们可以求的是以i为右端点的询问,就是 ss[l] ....ss[r]( r == i ) 中的最大值;
到这里还有一个问题需要解决, 重复出现的值不计算??
可以这样:在更新a[i]的时候,更新区间不是1---i 而是pre[a[i]] --- i (pre[a[i]]是a[i]上一次出现的位置);这样就可以解决重复计算问题
线段树结构中:
curmax表示此区间内的最优值
prelazy即将下传的最大值;
lazy为即将下传的总值;
sum表示的区间内 max( s[] );
#include
#include
#include
#include
#include
#include
#include
#include
参考题解 : http://hi.baidu.com/lemon_workshop/item/2bcf00cf47e35a2da1b50a43