STL
学了一发set。
用两个set,一个维护全局的差值,一个维护每个位置的差值。
对每个位置记录起始元素和最终元素,就可以用set维护了。
map用来判断元素是否存在,堆快速得出答案。
代码:
#include<map>
#include<set>
#include<queue>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 500005
#define F inline
using namespace std;
const int inf=1e9;
int n,m,st[N],ed[N];
char s[15];
multiset<int>a,b;
map<int,int>mp;
priority_queue<int,vector<int>,greater<int> >q;
F int _read(){
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
F void writec(int x){ if (x>9) writec(x/10); putchar(x%10+48); }
F void _write(int x){ writec(x),putchar('\n'); }
void nsrt(int x){ if (!mp[x]) a.insert(x); mp[x]++; }
void dlt(int x){ mp[x]--; if (!mp[x]) a.erase(x); }
void push(int x){
int l=*--b.lower_bound(x),r=*b.lower_bound(x);
q.push(min(x-l,r-x)),b.insert(x);
}
int main(){
n=_read(),m=_read(),b.insert(inf),b.insert(-inf);
for (int i=1;i<=n;i++) st[i]=ed[i]=_read(),push(ed[i]);
for (int i=2;i<=n;i++) nsrt(abs(st[i]-st[i-1]));
while (m--){
char s[15]; scanf("%s",s); int x,w;
switch (s[4]){
case 'R':
x=_read(),w=_read();
if (x!=n) dlt(abs(ed[x]-st[x+1]));
nsrt(abs(ed[x]-w)),nsrt(abs(w-st[x+1]));
ed[x]=w,push(w); break;
case 'S': _write(q.top()); break;
case 'G': _write(*a.begin()); break;
}
}
return 0;
}