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

【SPOJ】4487 Can you answer these queries VI

2012-08-29 15:27 393 查看
仍然是询问区间最大连续和,只不过多了插入和删除操作。

线段树搞不定了。。伸展树来了。

插入删除偷懒那样写了,加了读入优化卡过的。

#include<cstdio>
#include<iostream>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define oo 1000000000
#define MAXN 200010
using namespace std;
int n, a[MAXN];
struct SplayTree {
int root, size;
int next[MAXN][2], pre[MAXN];
int num[MAXN], key[MAXN];
int left[MAXN], right[MAXN], sum[MAXN], val[MAXN];
void NewNode(int &x, int father, int nb) {
x = ++size;
next[x][0] = next[x][1] = 0;
pre[x] = father;
num[x] = 1;
key[x] = left[x] = right[x] = sum[x] = val[x] = nb;
}
inline void PushUp(int x) {
int L, R;
L = next[x][0], R = next[x][1];
num[x] = num[L] + num[R] + 1;
sum[x] = sum[L] + sum[R] + key[x];
left[x] = MAX(left[L],sum[L]+key[x]+MAX(left[R],0));
right[x] = MAX(right[R],sum[R]+key[x]+MAX(right[L],0));
val[x] = MAX(val[L],val[R]);
val[x] = MAX(val[x],key[x]+MAX(right[L],0)+MAX(left[R],0));
}
void Build(int L, int R, int &x, int father) {
if (L <= R) {
int mid = (L + R) >> 1;
NewNode(x, father, a[mid]);
Build(L, mid - 1, next[x][0], x);
Build(mid + 1, R, next[x][1], x);
PushUp(x);
}
}
void Init() {
size = root = 0;
next[0][0] = next[0][1] = 0;
pre[0] = 0;
sum[0] = num[0] = 0;
key[0] = left[0] = right[0] = val[0] = -oo;
NewNode(root, 0, -oo);
NewNode(next[root][1], root, -oo);
Build(1, n, next[next[root][1]][0], next[root][1]);
PushUp(next[root][1]);
PushUp(root);
}
void Rotate(int x, int kind) {
int y, z;
y = pre[x];
z = pre[y];
next[y][!kind] = next[x][kind];
pre[next[x][kind]] = y;
next[z][next[z][1] == y] = x;
pre[x] = z;
next[x][kind] = y;
pre[y] = x;
PushUp(y);
}
void Splay(int x, int goal) {
if (x != goal) {
while (pre[x] != goal) {
if (next[pre[x]][0] == x)
Rotate(x, 1);
else
Rotate(x, 0);
}
PushUp(x);
if (!goal)
root = x;
}
}
int Select(int k) {
int x;
for (x = root; num[next[x][0]] + 1 != k;) {
if (k <= num[next[x][0]])
x = next[x][0];
else {
k -= num[next[x][0]] + 1;
x = next[x][1];
}
}
return x;
}
void Insert(int k, int val) {
int a, b;
a = Select(k);
b = Select(k + 1);
Splay(a, 0);
Splay(b, a);
NewNode(next[b][0], b, val);
PushUp(b);
PushUp(a);
}
void Delete(int k) {
int a, b;
a = Select(k);
b = Select(k + 2);
Splay(a, 0);
Splay(b, a);
next[b][0] = 0;
PushUp(b);
PushUp(a);
}
void Update(int k, int val) {
int a;
a = Select(k + 1);
key[a] = val;
Splay(a, 0);
}
int Query(int x, int y) {
x = Select(x);
y = Select(y + 2);
Splay(x, 0);
Splay(y, x);
return val[next[y][0]];
}
} spt;
int INT() {
int res;
char ch;
bool neg;
while (ch = getchar(), !isdigit(ch) && ch != '-')
;
if (ch == '-') {
res = 0;
neg = true;
} else {
res = ch - '0';
neg = false;
}
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - '0';
return neg ? -res : res;
}
char CHAR() {
char res;
while (res = getchar(), !isalpha(res))
;
return res;
}
int main() {
char ch;
int i, q, x, y;
while (~scanf("%d", &n)) {
for (i = 1; i <= n; i++)
a[i] = INT();
spt.Init();
q = INT();
while (q--) {
ch = CHAR(), x = INT();
if (ch != 'D')
y = INT();
if (ch == 'I')
spt.Insert(x, y);
else if (ch == 'D')
spt.Delete(x);
else if (ch == 'R')
spt.Update(x, y);
else
printf("%d\n", spt.Query(x, y));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: