用普通线段树\平衡树无限TLE!!!
然而ZKW线段树水过,OLZ神犇ZKW!!!
AC code:
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=8000010;
const int INF=1<<29;
int n,m,first;
struct nod{
int mx,mi;
};
struct Segtree{
nod a[N];
Segtree(){
first=1<<(int)(log2(n+1)+2);
for(int i=1;i<=(first<<1)-1;i++){
a[i].mx=-INF;a[i].mi=INF;
}
}
void insert(int x){
int i=first+x+1;
for(a[i].mx=a[i].mi=x,i>>=1;i;i>>=1){
a[i].mx=max(a[i<<1].mx,a[(i<<1)^1].mx);
a[i].mi=min(a[i<<1].mi,a[(i<<1)^1].mi);
}
}
void erase(int x){
int i=first+x+1;
for(a[i].mx=-INF,a[i].mi=INF,i>>=1;i;i>>=1){
a[i].mx=max(a[i<<1].mx,a[(i<<1)^1].mx);
a[i].mi=min(a[i<<1].mi,a[(i<<1)^1].mi);
}
}
void querymax(){
printf("%d\n",a[1].mx!=-INF?a[1].mx:-1);
}
void querymin(){
printf("%d\n",a[1].mi!=INF?a[1].mi:-1);
}
int getmax(int L,int R){
int ans=-INF,i=first+L,j=first+R+2;
for(;i+1!=j;i>>=1,j>>=1){
if(!(i&1)) ans=max(ans,a[i^1].mx);
if(j&1) ans=max(ans,a[j^1].mx);
}
return ans;
}
int getmin(int L,int R){
int ans=INF,i=first+L,j=first+R+2;
for(;i+1!=j;i>>=1,j>>=1){
if(!(i&1)) ans=min(ans,a[i^1].mi);
if(j&1) ans=min(ans,a[j^1].mi);
}
return ans;
}
void getpre(int x){
int ans=getmax(0,x-1);
printf("%d\n",ans!=-INF?ans:-1);
}
void getsuc(int x){
int ans=getmin(x+1,n-1);
printf("%d\n",ans!=INF?ans:-1);
}
void find(int x){
printf("%d\n",a[first+x+1].mi!=INF?1:-1);
}
};
int main(){
scanf("%d%d",&n,&m);
Segtree T;
for(int i=1;i<=m;i++){
int k,x;
scanf("%d",&k);
if(k!=3&&k!=4) scanf("%d",&x);
if(k==1) T.insert(x);
else if(k==2) T.erase(x);
else if(k==3) T.querymin();
else if(k==4) T.querymax();
else if(k==5) T.getpre(x);
else if(k==6) T.getsuc(x);
else T.find(x);
}
return 0;
}