SPOJ/GSS3:Can you answer these queries III(线段树)

原创 2012年03月30日 16:46:49

http://www.spoj.pl/problems/GSS3/

题意:给出一个数列,求某个区间内的最大子序列和,并进行对某些点的更新。GSS1是个不更新只查询的简化版题目,差别不大。

跟hdu3397有点像,统计量也很像,但是犯了经验主义的错误,左起最大字段和=左区间左起最大字段和  或   左区间和+右区间左起最大字段和(如果左区间左起最大字段和==左区间和)是错误的,例如:100 -1 100 100,因此pushup操作应改为maxl=MAX(L[maxl],L[sum]+R[maxl]);

spoj对java支持不是很好,所以翻译了一个c--版本才能AC

#include<cstdio>
#include <algorithm>
using namespace std;
struct SegTree {
	struct node {
		int left, right;
		int max, maxl, maxr, sum;
		int mid() {
			return (left + right) >> 1;
		}
		void init(int k) {
			max = maxl = maxr = sum = k;
		}
	} tree[150010];
	void init(int left, int right, int idx, int a[]) {
		tree[idx].left = left;
		tree[idx].right = right;
		if (left == right) {
			tree[idx].init(a[left]);
			return;
		}
		int mid = tree[idx].mid();
		init(left, mid, idx << 1, a);
		init(mid + 1, right, (idx << 1)+1, a);
		pushup(idx);
	}
	void update(int pos, int idx, int value) {
		if (tree[idx].left == tree[idx].right && pos == tree[idx].left) {
			tree[idx].init(value);
			return;
		}
		int mid = tree[idx].mid();
		if (pos <= mid)
			update(pos, idx << 1, value);
		else
			update(pos, (idx << 1)+1, value);
		pushup(idx);
	}
	node query(int left, int right, int idx) {
		if (left == tree[idx].left && right == tree[idx].right) {
			return tree[idx];
		}
		int mid = tree[idx].mid();
		if (right <= mid)
			return query(left, right, idx << 1);
		else if (left > mid)
			return query(left, right, (idx << 1) + 1);
		else {
			node ll = query(left, mid, idx << 1);
			node rr = query(mid + 1, right, (idx << 1) + 1);
			node ans;
			ans.sum = ll.sum + rr.sum;
			int a = ll.max;
			int b = rr.max;
			int c = ll.maxr + rr.maxl;
			ans.max = max(max(a, b), c);
			ans.maxl = max(ll.maxl, ll.sum + rr.maxl);
			ans.maxr = max(rr.maxr, rr.sum + ll.maxr);
			return ans;
		}
	}
	int getanswer(int l, int r) {
		return query(l, r, 1).max;
	}
	void pushup(int idx) {
		if (tree[idx].left == tree[idx].right)
			return;
		int a = tree[idx << 1].max;
		int b = tree[(idx << 1) + 1].max;
		int c = tree[idx << 1].maxr + tree[(idx << 1) + 1].maxl;
		tree[idx].max = max(max(a, b), c);
		tree[idx].sum = tree[idx << 1].sum + tree[(idx << 1) + 1].sum;
		a = tree[idx << 1].maxl;
		b = tree[(idx << 1) + 1].maxl + tree[idx << 1].sum;
		tree[idx].maxl = max(a, b);
		a = tree[(idx << 1) + 1].maxr;
		b = tree[(idx << 1) + 1].sum + tree[idx << 1].maxr;
		tree[idx].maxr = max(a, b);
	}
} st;
 
int main() {
	int n, m, x, y, op;
	int a[50010];
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		scanf("%d", a + i);
	st.init(1, n, 1, a);
	scanf("%d", &m);
	while (m-- > 0) {
		scanf("%d%d%d", &op, &x, &y);
		if (op == 0)
			st.update(x,1,y);
		else
			printf("%d\n", st.getanswer(x, y));
	}
	return 0;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

SPOJ 1716 GSS3 Can you answer these queries III 线段树区间合并

传送门:SPOJ 1716 题意 求动态区间最大子段和 题解 线段树区间合并维护区间和, 左右连续最大字段和, 最大字段和 AC code:#include #include #include...
  • ADjky
  • ADjky
  • 2017年01月17日 17:21
  • 143

【SPOJ-GSS1】Can you answer these queries I【线段树】【最大子段和】

题意: 给出一些数,一些询问,每次询问一段区间内最大的子段和是多少。 无修改的小白逛公园... #include #include using namespace std; co...

SPOJ 2916 Can you answer these queries V(GSS5 线段树)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:和GSS3类似,只不...

【线段树】spoj GSS2 Can you answer these queries II

写了三个小时的线段树也是醉了 = = PushDown手贱了一下于是一直23333 #include #include #include #include #include u...

SPOJ GSS1 Can you answer these queries I (线段树求区间最大连续和)

题目大意给定一个数列,并给出一些询问的区间,求出询问区间内的最大连续区间和。解题思路直接上线段树,但是区间合并的时候遇到了一些困难。首先我们考虑,想要达到 logn 级别的访问时间,对于线段树的每个节...

SPOJ 2713. Can you answer these queries IV(GSS4 线段树)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove  题目:给出N个数,两种操...

[SPOJ1557][GSS2][线段树]Can you answer these queries II[好题]

[SPOJ1557][GSS2][线段树]Can you answer these queries II[好题]

SPOJ 1557 Can you answer these queries II(GSS2 线段树)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove  题目:求出区间的最大子段...

Spoj 1716 Can you answer these queries III 线段树 单点修改 区间求最大子段和

题目链接:点击打开链接 == 原来写1的时候已经把更新函数写好了。。 #include #include #include #include #include #include ...

【SPOJ】1716 Can you answer these queries III 线段树

传送门:【SPOJ】1716 Can you answer these queries III
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SPOJ/GSS3:Can you answer these queries III(线段树)
举报原因:
原因补充:

(最多只允许输入30个字)