SPOJ GSS2 Can you answer these queries II
2015-04-09 19:00
459 查看
题意:
给定一个序列和m个询问, 要求求出一个区间内最大连续子段和, 并且相同的数只能算一次。
思路:
把询问离线, 按右端点排序,从小到大扫描询问, 假设当前询问的右端点是r, 用线段树维护4个值:
mx_s: 左端点为ll,右端点在[l,r]的最大连续子段和(也就是最优的情况)。
s:左端点为ll, 到r的区间和。
mx_add: 区间的最优懒惰标记。
add: 区间的所有懒惰标记。
更新第i个数时候, 把pre[a[i]] + 1 ~ i都加上a[i]。
查询的时候就是l~r的mx_s
重点在push_up和push_down...
给定一个序列和m个询问, 要求求出一个区间内最大连续子段和, 并且相同的数只能算一次。
思路:
把询问离线, 按右端点排序,从小到大扫描询问, 假设当前询问的右端点是r, 用线段树维护4个值:
mx_s: 左端点为ll,右端点在[l,r]的最大连续子段和(也就是最优的情况)。
s:左端点为ll, 到r的区间和。
mx_add: 区间的最优懒惰标记。
add: 区间的所有懒惰标记。
更新第i个数时候, 把pre[a[i]] + 1 ~ i都加上a[i]。
查询的时候就是l~r的mx_s
重点在push_up和push_down...
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <cmath> #include <queue> #include <iomanip> #include <map> #include <set> #include <algorithm> using namespace std; #define N 100020 #define mod 1000000007 #define mxe 2000020 #define MP make_pair #define PB push_back #define LL long long #define ULL unsigned LL #define inf 0x3f3f3f3f #define ls (i << 1) #define rs (ls | 1) #define md ((ll + rr) >> 1) #define lson ll, md, ls #define rson md + 1, rr, rs #pragma comment(linker, "/STACK:1024000000,1024000000") int n, m; int s[N<<2], mx_s[N<<2], add[N<<2], mx_add[N<<2]; int a , pre[N*2]; struct query { int l, r, ans; }p ; int id ; bool cmp(int i, int j) { return p[i].r < p[j].r; } void add_val(int i, int v) { add[i] += v; mx_add[i] = max(mx_add[i], add[i]); s[i] += v; mx_s[i] = max(mx_s[i], s[i]); } void push_down(int i) { mx_add[ls] = max(mx_add[ls], add[ls] + mx_add[i]); add[ls] += add[i]; mx_s[ls] = max(mx_s[ls], s[ls] + mx_add[i]); s[ls] += add[i]; mx_add[rs] = max(mx_add[rs], add[rs] + mx_add[i]); add[rs] += add[i]; mx_s[rs] = max(mx_s[rs], s[rs] + mx_add[i]); s[rs] += add[i]; add[i] = mx_add[i] = 0; } void push_up(int i) { mx_s[i] = max(mx_s[ls], mx_s[rs]); s[i] = max(s[ls], s[rs]); } void update(int l, int r, int v, int ll, int rr, int i) { if(ll == l && rr == r) { add_val(i, v); return; } push_down(i); if(r <= md) update(l, r, v, lson); else if(l > md) update(l, r, v, rson); else update(l, md, v, lson), update(md + 1, r, v, rson); push_up(i); } int query(int l, int r, int ll, int rr, int i) { if(ll == l && rr == r) return mx_s[i]; push_down(i); if(r <= md) return query(l, r, lson); if(l > md) return query(l, r, rson); return max(query(l, md, lson), query(md + 1, r, rson)); } int main() { // freopen("tt.txt", "r", stdin); while(scanf("%d", &n) != EOF) { for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); scanf("%d", &m); for(int i = 1; i <= m; ++i) { scanf("%d%d", &p[i].l, &p[i].r); id[i] = i; } sort(id + 1, id + m + 1, cmp); memset(s, 0, sizeof s); memset(mx_s, 0, sizeof mx_s); memset(add, 0, sizeof add); memset(mx_add, 0, sizeof mx_add); memset(pre, 0, sizeof pre); int j = 1; for(int i = 1; i <= m; ++i) { int u = id[i]; while(j <= n && j <= p[u].r) { update(pre[a[j]+N] + 1, j, a[j], 1, n, 1); pre[a[j]+N] = j; ++j; } p[u].ans = query(p[u].l, p[u].r, 1, n, 1); } for(int i = 1; i <= m; ++i) printf("%d\n", p[i].ans); } return 0; }
相关文章推荐
- [SPOJ1557][GSS2][线段树]Can you answer these queries II[好题]
- [SPOJ GSS2] Can you answer these queries II [线段树]
- SPOJ 1557 Can you answer these queries II(GSS2 线段树)
- BZOJ 2482 || SPOJ GSS2 Can you answer these queries II(线段树 离线 后缀和)
- SPOJ GSS2 Can you answer these queries II
- SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)
- SPOJ GSS2 Can you answer these queries II
- 【线段树】spoj GSS2 Can you answer these queries II
- spoj 1557 Can you answer these queries II (gss2)线段树
- bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树
- SPOJ GSS2 Can you answer these queries II ——线段树
- 【SPOJ - GSS2】Can you answer these queries II(线段树)
- spojGSS2 1557 Can you answer these queries II(成段更新)
- SPOJ GSS2 Can you answer these queries II
- GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树
- SPOJ GSS1 Can you answer these queries I
- SPOJ 4487. Can you answer these queries VI(GSS6 Splay tree)
- 【SPOJ】1557 Can you answer these queries II 线段树
- SPOJ GSS1 Can you answer these queries I[线段树]
- SPOJ GSS3 Can you answer these queries III