有生之年第一道浙江省选题(虽然历史久远并且很水)
记录每个位置数列的左端点和右端点
维护两颗splay 一颗维护全局最小差值,一颗维护相邻最小差值
对于全局splay:每次插入时记录路径取差值min即可
对于相邻最小差值splay:删除当前位置右端点和下一个位置左端点的差值,,再插入当前值和当前位置右端点差值 和 当前值和下一个位置左端点差值
当我写完200行的程序调到崩溃 后看到了hzwer的程序只有80行时
我是震惊的、、、
看来stl是很好的东西。。
惨不忍睹的代码:
#include<iostream>
#include<cstdio>
using namespace std;
#include<cmath>
int min1=1e9,min2=1e9,n,m,i,x,y,do12;
string str;
struct la
{
int l,r;
}a[900000];
struct tree
{
int zhi,cnt;
tree *ch[2],*fu;
int getwh()
{
return fu->ch[0]==this?0:1;
}
void set(int wh,tree *child);
}p[5000000],*null,*root1,*root2;
void tree::set(int wh,tree *child)
{
ch[wh]=child;
if(child!=null)child->fu=this;
}
int tot;
tree *xin(int k)
{
tree *now=p+ ++tot;
now->zhi=k;
now->cnt=1;
now->ch[0]=now->ch[1]=now->fu=null;
return now;
}
inline void rotate(tree *&now)
{
tree *fu=now->fu;
tree *ye=now->fu->fu;
int wh=now->getwh();
fu->set(wh,now->ch[wh^1]);
now->set(wh^1,fu);
now->fu=ye;
if(ye!=null)
ye->ch[ye->ch[0]==fu?0:1]=now;
}
inline void splay(tree *now,tree *tar)
{
for(;now->fu!=tar;rotate(now))
if(now->fu->fu!=tar)
now->getwh()==now->fu->getwh()?rotate(now->fu):rotate(now);
if(tar==null)
do12==0?root1=now:root2=now;
}
void ins(int k)
{//cout<<k;
tree *now=do12==0?root1:root2,*last=null,*newone=xin(k);
while(now!=null)
{
last=now;
if(do12==0)min1=min(now->zhi-k>0?now->zhi-k:k-now->zhi,min1);
// cout<<now->zhi<<" ";
if(now->zhi==k)
{
now->cnt++;
splay(now,null);
return;
}
if(k>now->zhi)now=now->ch[1];
else now=now->ch[0];
}
if(last==null)do12==0?root1=newone:root2=newone;
if(last->zhi>k)last->set(0,newone);
if(last->zhi<k)last->set(1,newone);
splay(newone,null);
}
inline tree *find(int zhi)
{
tree *now=root2;
while(now!=null)
{
if(now->zhi==zhi)break;
if(now->zhi>zhi)
now=now->ch[0];
else now=now->ch[1];
}
if(now!=null)splay(now,null);
return now;
}
void del(int value)
{
tree *now = find(value);
if (now == null) return;
if (now->cnt > 1)
{
now->cnt--;
return;
}
if (now->ch[0] == null && now->ch[1] == null)
root2 = null;
else if (now->ch[1] == null)
{
now->ch[0]->fu = null;
root2 = now->ch[0];
}
else if (now->ch[0] == null)
{
now->ch[1]->fu = null;
root2 = now->ch[1];
}
else
{
tree *_ = now->ch[0];
while (_->ch[1] != null) _ = _->ch[1];
splay(_, now);
_->set(1, now->ch[1]);
_->fu = null;
root2 = _;
}
}
int main()
{
// freopen("form.in","r",stdin);
// freopen("form.out","w",stdout);
null=p;
root1=root2=null;
null->ch[0]=null->ch[1]=null->fu=null;
null->zhi=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d",&x);
do12=0;
ins(x);
// cout<<x;
a[i].r=a[i].l=x;
if(i>1)
{
do12=1;
ins(x-a[i-1].l>0?x-a[i-1].l:a[i-1].l-x);
//cout<<a[i-1].l-x<<"oo ";
}
}
//cout<<root->ch[1]->zhi;
for(i=1;i<=m;i++)
{
cin>>str;
if(str=="INSERT")
{
scanf("%d%d",&x,&y);
do12=0;
ins(y);
do12=1;
ins(a[x].r-y>0?a[x].r-y:y-a[x].r);
if(x<n)
{
del(a[x].r-a[x+1].l>0?a[x].r-a[x+1].l:a[x+1].l-a[x].r);
// cout<<a[x].r-a[x+1].l<<" p ";
ins(a[x+1].l-y>0?a[x+1].l-y:y-a[x+1].l);
} a[x].r=y;
}else if(str=="MIN_SORT_GAP")
{
printf("%d\n",min1);
}else
{
tree *now=root2,*last=null;
while(now!=null)last=now,now=now->ch[0];
printf("%d\n",last->zhi);
}
}
}