SP1557 GSS2 Can you answer these queries II

求区间最大子段和,而且不能有重复元素的
为了避免重复元素,我们用扫描线

把所有询问离线下来,按照r升序排序

对于一个元素a[i],每次扫描到,就在pre[a[i]]+1~i 加入元素 a[i],然后查询查询区间的历史区间最大值,然后这个历史区间最大值就是[l,l+1],[l,l+2]***[l,r]的
最大子段和就是在[l],[l+1][r]这些左端点的区间的最大值里面挑选最大值
我们查询[l,r]的历史区间最值就是这个max([l,l],[l,l + 1],[l,l + 2].....[l,r])里面的历史区间最值,就是[l,.........] [l + 1.......] [l + 2.............] [r,......]的最大值
可能就是这样吧。

const int N = 1e5 + 79;
int a[N], q, n;
struct question {
	int l, r, id;
	inline bool operator <(const question &rhs) {
		return r < rhs.r;
	}
} t[N];
int pre[N * 2];
struct SegmentTree {
	lxl mx[N << 1], Hismx[N << 1], tag[N << 1], Histag[N << 1];
	int lc[N << 1], rc[N << 1], rt, cnt;

	inline void pushup(int p) {
		mx[p] = max(mx[lc[p]], mx[rc[p]]);
		Hismx[p] = max(Hismx[lc[p]], Hismx[rc[p]]);
		tag[p] = Histag[p] = 0;
	}
	inline void pushdown(int p) {
		if(tag[p] == 0 && Histag[p] == 0) return ;

		if(!lc[p]) lc[p] = ++cnt;
		Hismx[lc[p]] = max(Hismx[lc[p]], mx[lc[p]] + Histag[p]);
		Histag[lc[p]] = max(Histag[lc[p]], tag[lc[p]] + Histag[p]);
		mx[lc[p]] += tag[p];
		tag[lc[p]] += tag[p];

		if(!rc[p]) rc[p] = ++cnt;

		Hismx[rc[p]] = max(Hismx[rc[p]], mx[rc[p]] + Histag[p]);
		Histag[rc[p]] = max(Histag[rc[p]], tag[rc[p]] + Histag[p]);
		mx[rc[p]] += tag[p];
		tag[rc[p]] += tag[p];

		tag[p] = Histag[p] = 0;
	}


	inline void add(int &p, int L, int R, int ll, int rr, lxl val) {
		if(!p) p = ++cnt;
		if(ll <= L && rr >= R) {
			mx[p] += val;
			Hismx[p] = max(Hismx[p], mx[p]);
			tag[p] += val;
			Histag[p] = max(Histag[p], tag[p]);
			return ;
		}
		pushdown(p);
		int mid(L + R >> 1);
		if(ll <= mid) add(lc[p], L, mid, ll, rr, val);
		if(rr > mid) add(rc[p], mid + 1, R, ll, rr, val);
		pushup(p);
	}

	inline lxl query(int &p, int L, int R, int ll, int rr) {
		if(!p) return -1e18;
		if(ll <= L && rr >= R) {
			return Hismx[p];
		}
		pushdown(p);
		int mid(L + R >> 1);
		lxl ans = -1e18;
		if(ll <= mid) ans = max(ans, query(lc[p], L, mid, ll, rr));
		if(rr > mid) ans = max(ans, query(rc[p], mid + 1, R, ll, rr));
		return ans;
	}
} S;


lxl ans[N];
int main() {
	read(n);
	rep(i, 1, n) {
		read(a[i]);
	}
	read(q);
	rep(i, 1, q) {
		read(t[i].l);
		read(t[i].r);
		t[i].id = i;
	}
	std::sort(t + 1, t + q + 1);

	int j(1);
	rep(i, 1, n) {
		S.add(S.rt, 1, n, pre[a[i] + 100000] + 1, i, a[i]);
		pre[a[i] + 100000] = i;
		while(t[j].r == i && j <= q) {
			ans[t[j].id] = S.query(S.rt, 1, n, t[j].l, t[j].r);
			++j;
		}
	}

	rep(i, 1, q) {
		out(ans[i], '\n');
	}
	return 0;
}

本文来自博客园,作者:{2519},转载请注明原文链接:https://www.cnblogs.com/QQ2519/p/15572939.html

原文地址:https://www.cnblogs.com/QQ2519/p/15572939.html