您的位置:首页 > 产品设计 > UI/UE

【SPOJ】1557 Can you answer these queries II

2012-08-30 18:08 281 查看
询问区间最大连续和,相同的只能算一次。可以不取,即为0

线段树在线做不到,只好离线搞。

一般最大连续和,都是以一个点为起点,往左或往右。其实,还可以以一个点为起点,往上最大是多少。

用pos标记一个数之前更新到的位置。

比如:-3 2 -3 1

用线段树成段覆盖:(越下方越早更新到)

1 1 1 1

-3 -3

2 2

-3

nowsum表示当前深度积累的总和。

nowup表示当前深度从底往上的最大值。

totsum,totup同理,表示的是以某个叶子为起点对应的值。

加上读入优化,快了2s……

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define MAXN 200010
#define S 100000
typedef long long LL;
using namespace std;
struct seg {
int left, right, id;
};
struct node {
LL nowsum, nowup;
LL totsum, totup;
};
seg p[MAXN];
node tree[MAXN << 2];
LL a[MAXN], ans[MAXN];
int pos[MAXN];
inline bool cmp(seg a, seg b) {
return a.right < b.right;
}
inline LL MAX(LL x, LL y) {
return x > y ? x : y;
}
void Build(int L, int R, int rt) {
tree[rt].nowsum = tree[rt].nowup = 0;
tree[rt].totsum = tree[rt].totup = 0;
if (L != R) {
int mid = (L + R) >> 1;
Build(L, mid, rt << 1);
Build(mid + 1, R, rt << 1 | 1);
}
}
inline void PushUp(int rt) {
tree[rt].totsum = MAX(tree[rt << 1].totsum, tree[rt << 1 | 1].totsum)
+ tree[rt].nowsum;
tree[rt].totup = MAX(tree[rt << 1].totup, tree[rt << 1 | 1].totup);
tree[rt].totup = MAX(tree[rt].totup,
MAX(tree[rt << 1].totsum, tree[rt << 1 | 1].totsum)
+ tree[rt].nowup);
}
inline void Down(int a, int b) {
tree[b].nowup = MAX(tree[b].nowup, tree[b].nowsum + tree[a].nowup);
tree[b].nowsum += tree[a].nowsum;
PushUp(b);
}
inline void PushDown(int rt) {
Down(rt, rt << 1);
Down(rt, rt << 1 | 1);
tree[rt].nowsum = tree[rt].nowup = 0;
}
void Update(int x, int y, int val, int L, int R, int rt) {
if (x <= L && R <= y) {
tree[rt].nowsum += val;
tree[rt].nowup = MAX(tree[rt].nowup, tree[rt].nowsum);
PushUp(rt);
} else {
int mid = (L + R) >> 1;
PushDown(rt);
if (x <= mid)
Update(x, y, val, L, mid, rt << 1);
if (y > mid)
Update(x, y, val, mid + 1, R, rt << 1 | 1);
PushUp(rt);
}
}
LL Query(int x, int y, int L, int R, int rt) {
if (x <= L && R <= y)
return tree[rt].totup;
else {
int mid = (L + R) >> 1;
LL res = 0;
PushDown(rt);
if (x <= mid)
res = MAX(res, Query(x, y, L, mid, rt << 1));
if (y > mid)
res = MAX(res, Query(x, y, mid + 1, R, rt << 1 | 1));
return res;
}
}
int INT() {
int res;
char ch;
bool neg;
while (ch = getchar_unlocked(), !isdigit(ch) && ch != '-')
;
if (ch == '-') {
res = 0;
neg = true;
} else {
res = ch - '0';
neg = false;
}
while (ch = getchar_unlocked(), isdigit(ch))
res = res * 10 + ch - '0';
return neg ? -res : res;
}
int main() {
int n, i, j, q;
while (~scanf("%d", &n)) {
Build(1, n, 1);
memset(pos, 0, sizeof(pos));
for (i = 1; i <= n; i++)
a[i] = INT();
q = INT();
for (i = 0; i < q; i++) {
p[i].left = INT(), p[i].right = INT();
p[i].id = i;
}
sort(p, p + q, cmp);
for (i = 1, j = 0; i <= n && j < q; i++) {
Update(pos[a[i] + S] + 1, i, a[i], 1, n, 1);
pos[a[i] + S] = i;
for (; j < q && i == p[j].right; j++)
ans[p[j].id] = Query(p[j].left, p[j].right, 1, n, 1);
}
for (i = 0; i < q; i++)
printf("%lld\n", ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: