题目
做法
仿佛喝了一桶水
一眼平衡树,找前驱和后继,太暴力了,平衡树只会\(splay\),码量出奇的大
找到\(x\)点往左右扩散的区间,当然线段树也能做
左端点和右端点?明明一个set就能解决的事
My complete code
#include<cstdio>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<set>
using namespace std;
typedef long long LL;
const LL maxn=2000000;
inline LL Read(){
LL x(0),f(1);char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
return x*f;
}
LL n,m,top;
LL visit[maxn],sta[maxn];
set<LL> Set;
set<LL> ::iterator it,pre,next;
int main(){
n=Read(),m=Read();
Set.insert(0),Set.insert(n+1);
while(m--){
char c; scanf(" %c",&c);
if(c=='D'){
LL now(Read());
if(!visit[now]){
visit[now]=1,Set.insert(now),
sta[++top]=now;
}
}else if(c=='Q'){
LL now(Read());
if(visit[now]){
printf("0\n"); continue;
}
Set.insert(now),
it=Set.find(now);
pre=it,--pre;
next=it,++next;
printf("%lld\n",*next-*pre-1);
Set.erase(now);
}else{
if(top){
LL now(sta[top--]);
Set.erase(now),
visit[now]=0;
}
}
}
}