Splay.
看着自己的早期代码也是醉了…
AC code:
#include <cstdio>
#include <cstdlib>
#include <cstring>
const int N=1000010;
int n,m;
int cnt[N];
int Min(int x,int y)
{
return x<y?x:y;
}
int Min(int x,int y,int z)
{
return Min(Min(x,y),z);
}
int Abs(int x)
{
return x>0?x:-x;
}
struct Vnode
{
int val;
Vnode *Prev,*Ch[2];
};
struct Nnode
{
int n1,n2,val,k,mink;
Nnode *Prev,*Ch[2];
};
struct V_Splay
{
int ans;
Vnode *NIL,*root,*pool;
V_Splay(int size)
{
pool=(Vnode*)malloc(size*sizeof(Vnode));
NIL=root=pool++;
NIL->Ch[0]=NIL->Ch[1]=NULL;
ans=1<<30;
}
void rotate(Vnode *x,bool type)
{
Vnode *y=x->Prev,*z=y->Prev,*b=x->Ch[type^1];
b->Prev=y;
y->Prev=x;
x->Prev=z;
y->Ch[type]=b;
x->Ch[type^1]=y;
if(z->Ch[0]==y) z->Ch[0]=x;
if(z->Ch[1]==y) z->Ch[1]=x;
}
void splay(Vnode *x,Vnode *obj)
{
while(x->Prev!=obj)
{
Vnode *y=x->Prev,*z=y->Prev;
if(z==NIL){
if(y->Ch[0]==x) rotate(x,0);
else rotate(x,1);
}
else{
if(z->Ch[0]==y&&y->Ch[0]==x){
rotate(y,0);
rotate(x,0);
}
else if(z->Ch[1]==y&&y->Ch[1]==x){
rotate(y,1);
rotate(x,1);
}
else if(z->Ch[1]==y){
rotate(x,0);
rotate(x,1);
}
else{
rotate(x,1);
rotate(x,0);
}
}
}
if(obj==NIL) root=x;
}
void insert(int key)
{
_insert(&root,key,NIL);
}
void _insert(Vnode **p,int key,Vnode *last)
{
while(1)
{
if(*p==NIL){
*p=pool++;
(*p)->val=key;
(*p)->Prev=last;
(*p)->Ch[0]=(*p)->Ch[1]=NIL;
splay(*p,NIL);
Vnode *t=root->Ch[0];
while(t!=NIL&&t->Ch[1]!=NIL) t=t->Ch[1];
if(t!=NIL) ans=Min(ans,root->val-t->val);
t=root->Ch[1];
while(t!=NIL&&t->Ch[0]!=NIL) t=t->Ch[0];
if(t!=NIL) ans=Min(ans,t->val-root->val);
return ;
}
bool flag=key>(*p)->val;
last=*p;
p=&(*p)->Ch[flag];
}
}
};
struct N_Splay
{
int ans;
Nnode *NIL,*root,*pool;
N_Splay(int size)
{
pool=(Nnode*)malloc(size*sizeof(Nnode));
NIL=root=pool++;
NIL->Ch[0]=NIL->Ch[1]=NULL;
NIL->mink=ans=1<<30;
}
void rotate(Nnode *x,bool type)
{
Nnode *y=x->Prev,*z=y->Prev,*b=x->Ch[type^1];
b->Prev=y;
y->Prev=x;
x->Prev=z;
y->Ch[type]=b;
x->Ch[type^1]=y;
if(z->Ch[0]==y) z->Ch[0]=x;
if(z->Ch[1]==y) z->Ch[1]=x;
x->mink=Min(x->k,x->Ch[0]->mink,x->Ch[1]->mink);
y->mink=Min(y->k,y->Ch[0]->mink,y->Ch[1]->mink);
}
void splay(Nnode *x,Nnode *obj)
{
while(x->Prev!=obj){
Nnode *y=x->Prev,*z=y->Prev;
if(z==NIL){
if(y->Ch[0]==x) rotate(x,0);
else rotate(x,1);
}
else{
if(z->Ch[0]==y&&y->Ch[0]==x){
rotate(y,0);
rotate(x,0);
}
else if(z->Ch[1]==y&&y->Ch[1]==x){
rotate(y,1);
rotate(x,1);
}
else if(z->Ch[1]==y){
rotate(x,0);
rotate(x,1);
}
else{
rotate(x,1);
rotate(x,0);
}
}
}
if(obj==NIL) root=x;
}
void insert(int key,int num1,int num2)
{
_insert(&root,key,num1,num2,NIL);
}
void _insert(Nnode **p,int key,int num1,int num2,Nnode *last)
{
while(1)
{
if(*p==NIL){
*p=pool++;
(*p)->val=key;
(*p)->n1=num1;
(*p)->n2=num2;
(*p)->Prev=last;
(*p)->mink=(*p)->k=1<<30;
(*p)->Ch[0]=(*p)->Ch[1]=NIL;
splay(*p,NIL);
Nnode *t=root->Ch[0];
while(t!=NIL&&t->Ch[1]!=NIL) t=t->Ch[1];
if(t!=NIL) root->k=Abs(root->val-t->val);
t=root->Ch[1];
while(t!=NIL&&t->Ch[0]!=NIL) t=t->Ch[0];
if(t!=NIL) t->k=Abs(root->val-t->val);
while(t!=NIL){
t->mink=Min(t->k,t->Ch[0]->mink,t->Ch[1]->mink);
t=t->Prev;
}
ans=root->mink=Min(root->k,root->Ch[0]->mink,root->Ch[1]->mink);
return ;
}
if(num1<(*p)->n1){
last=*p;
p=&(*p)->Ch[0];
}
else{
last=*p;
p=&(*p)->Ch[1];
}
}
}
};
int main()
{
scanf("%d%d",&n,&m);
V_Splay T1(N);
N_Splay T2(N);
for(int i=1;i<=n;i++){
int t;
scanf("%d",&t);
T1.insert(t);
T2.insert(t,i,0);
}
for(int i=1;i<=m;i++){
char s[101];
scanf("%s",s);
if(!strcmp(s,"MIN_GAP")) printf("%d\n",T2.ans);
else if(!strcmp(s,"MIN_SORT_GAP")) printf("%d\n",T1.ans);
else{
int p,t;
scanf("%d%d",&p,&t);
T1.insert(t);
T2.insert(t,p,++cnt[p]);
}
}
return 0;
}