# [BZOJ 1058] [ZJOI2007] 报表统计 【平衡树】

### 代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <map>
#include <set>

using namespace std;

const int MaxN = 500000 + 5, INF = 1000000015, MaxL = 25;

int n, m, MSG;
int A[MaxN], B[MaxN];

char Str[MaxL];

multiset<int> S, S2;
multiset<int>::iterator It, It2;

inline int gmax(int a, int b) {return a > b ? a : b;}
inline int gmin(int a, int b) {return a < b ? a : b;}
inline int Abs(int a) {return a < 0 ? -a : a;}

void Before(int x)
{
It = S.lower_bound(x);
if (It == S.end())
{
It--;
MSG = gmin(MSG, x - *It);
return;
}
if (*It == x)
{
MSG = 0;
return;
}
if (It == S.begin()) return;
It--;
MSG = gmin(MSG, x - *It);
}

void After(int x)
{
It = S.upper_bound(x);
if (It == S.end()) return;
MSG = gmin(MSG, *It - x);
}

int main()
{
scanf("%d%d", &n, &m);
S.clear(); S2.clear();
for (int i = 1; i <= n; ++i)
{
scanf("%d", &A[i]);
B[i] = A[i];
S.insert(A[i]);
}
for (int i = 2; i <= n; ++i)
S2.insert(Abs(A[i] - A[i - 1]));
MSG = INF;
for (int i = 1; i <= n; ++i)
{
S.erase(S.find(A[i]));
Before(A[i]);
After(A[i]);
S.insert(A[i]);
}
int Pos, Num;
for (int i = 1; i <= m; ++i)
{
scanf("%s", Str + 1);
if (Str[1] == 'I')
{
scanf("%d%d", &Pos, &Num);
Before(Num);
After(Num);
S.insert(Num);
if (Pos == n)
{
B[Pos] = Num;
continue;
}
S2.erase(S2.find(Abs(A[Pos + 1] - B[Pos])));
S2.insert(Abs(Num - B[Pos]));
S2.insert(Abs(A[Pos + 1] - Num));
B[Pos] = Num;
}
else if (Str[5] == 'G')
{
It2 = S2.begin();
printf("%d\n", *It2);
}
else
{
printf("%d\n", MSG);
}
}
return 0;
}

posted @ 2015-03-08 09:24  JoeFan  阅读(490)  评论(0编辑  收藏  举报