今天下午加半个晚上终于对照着lkx的代码学会splay了。。明天巩固一下再写点题。。
话说lkx的代码真是凝练,看的就很享受,话说我学splay学了快三个小时
智商真是硬伤。。。
不管怎么说还是写出来了hnoi2002的营业额统计,明天写hnoi2004的题
下面是代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define MAX 35000+9
using namespace std;
int father[MAX],l[MAX],r[MAX],val[MAX];
int a[MAX];
int n,i,top,ans=0;
int &root=l[0];
void rotate(int &x)
{
int y=father[x];
int z=father[y];
if(l[y]==x)//rotate_right
{
l[y]=r[x];
father[l[y]]=y;
r[x]=y;
father[r[x]]=x;
father[x]=z;
}
else//rotate_left
{
r[y]=l[x];
father[r[y]]=y;
l[x]=y;
father[l[x]]=x;
father[x]=z;
}
if(l[z]==y)
l[z]=x;
else
r[z]=x;
return;
}
void splay(int x)
{
int y,z;
while(y=father[x])
{
if(z=father[y])
{
if((l[z]==y)==(l[y]==x))
{
rotate(y);
rotate(x);
}
else
{
rotate(x);
rotate(x);
}
}
else
rotate(x);
}
}
int max_(int x)
{
if(!x)
return -0x7fffffff/3;
int k=x;
while(1)
{
if(r[k])
k=r[k];
else
break;
}
return val[k];
}
int min_(int x)
{
if(!x)
return 0x7fffffff/3;
int k=x;
while(1)
{
if(l[k])
k=l[k];
else
break;
}
return val[k];
}
int insert(int k)
{
int x=root;
if(!x)
{
top++;
father[top]=0;
val[top]=k;
l[0]=top;
return top;
}
int *temp;
while(1)
{
if(k<val[x])
temp=l;// turn left
else
temp=r;//turn right
if(!temp[x])
{
top++;
father[top]=x;
val[top]=k;
temp[x]=top;
return top;
}
else
x=temp[x];
}
}
int main()
{
cin>>n;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
splay(insert(a[1]));
ans=a[1];
for(i=2;i<=n;i++)
{
//scanf("%d",&a[i]);
splay(insert(a[i]));
//cout<<i<<' '<<ans<<endl;
ans+=min(a[i]-max_(l[root]),min_(r[root])-a[i]);
}
cout<<ans<<endl;
return 0;
}