SPOJ 1043 Can you answer these queries I
2012-04-18 12:50
267 查看
SPOJ_1043
今天顿时发现原来GSS系列一共有7道题,这个是其中的一道,只要在网址那改一下GGS*就可以找到其他的题目了。
这个题目可以用线段树去做,一个可行的思路就是计算出三个标记mc[](当前区间内最大的连续子串和),lc[](从当前区间左端点开始向右的最大的连续子串和),rc[](从当前区间右端点开始的向左的最大的连续子串和)。
查询的时候利用这三个标记进行计算就可以了。
今天顿时发现原来GSS系列一共有7道题,这个是其中的一道,只要在网址那改一下GGS*就可以找到其他的题目了。
这个题目可以用线段树去做,一个可行的思路就是计算出三个标记mc[](当前区间内最大的连续子串和),lc[](从当前区间左端点开始向右的最大的连续子串和),rc[](从当前区间右端点开始的向左的最大的连续子串和)。
查询的时候利用这三个标记进行计算就可以了。
#include<stdio.h> #include<string.h> #define MAXD 50010 int N, A[MAXD], mc[4 * MAXD], lc[4 * MAXD], rc[4 * MAXD]; int getmax(int x, int y) { return x > y ? x : y; } void update(int cur, int x, int y) { int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1; mc[cur] = getmax(mc[ls], mc[rs]); mc[cur] = getmax(mc[cur], rc[ls] + lc[rs]); lc[cur] = getmax(lc[ls], A[mid] - A[x - 1] + lc[rs]); rc[cur] = getmax(rc[rs], A[y] - A[mid] + rc[ls]); } void build(int cur, int x, int y) { int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1; if(x == y) { mc[cur] = lc[cur] = rc[cur] = A[x] - A[x - 1]; return ; } build(ls, x, mid); build(rs, mid + 1, y); update(cur, x, y); } void init() { int i; A[0] = 0; for(i = 1; i <= N; i ++) { scanf("%d", &A[i]); A[i] = A[i - 1] + A[i]; } build(1, 1, N); } int query(int cur, int x, int y, int s, int t, int flag, int &ans) { int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1; if(x >= s && y <= t) { ans = getmax(ans, mc[cur]); return flag == -1 ? lc[cur] : rc[cur]; } if(mid >= t) return query(ls, x, mid, s, t, -1, ans); else if(mid + 1 <= s) return query(rs, mid + 1, y, s, t, 1, ans); else { int ln, rn; ln = query(ls, x, mid, s, t, 1, ans); rn = query(rs, mid + 1, y, s, t, -1, ans); ans = getmax(ans, ln + rn); if(flag == -1) return getmax(lc[ls], A[mid] - A[x - 1] + rn); else return getmax(rc[rs], A[y] - A[mid] + ln); } } void solve() { int i, Q, x, y, ans; scanf("%d", &Q); for(i = 0; i < Q; i ++) { scanf("%d%d", &x, &y); ans = A[x] - A[x - 1]; query(1, 1, N, x, y, -1, ans); printf("%d\n", ans); } } int main() { while(scanf("%d", &N) == 1) { init(); solve(); } return 0; }
相关文章推荐
- 【SPOJ】 1043 Can you answer these queries I 线段树
- SPOJ 1043 Can you answer these queries I(GSS1 线段树)
- SPOJ 1043 Can you answer these queries I 求任意区间最大连续子段和 线段树
- 【SPOJ】1043 Can you answer these queries I
- spoj 1043 Can you answer these queries I
- 【SPOJ】1043 Can you answer these queries III
- SPOJ 1043 1043. Can you answer these queries I
- spoj 1043. Can you answer these queries I (线段树)
- 【线段树】 SPOJ 1043 Can you answer these queries I 区间合并
- 【线段树】 SPOJ 1043 Can you answer these queries I 区间合并
- Can you answer these queries(spoj 1043)
- spoj 1043 Can you answer these queries I(线段树)
- spoj 1043——Can you answer these queries I
- SPOJ 1043 Can you answer these queries I (超强线段树)
- GSS1 spoj 1043 Can you answer these queries I 最大子段和
- SPOJ 1043 Can you answer these queries I
- SPOJ 1043 1043. Can you answer these queries I
- SPOJ GSS3 Can you answer these queries III[线段树]
- 【SPOJ】Can you answer these queries III【线段树】
- [SPOJ GSS4] Can you answer these queries IV [树状数组+并查集][线段树+双向链表]