bzoj 1588 hnoi2002营业额统计 splay

来源:互联网 发布:floyd算法详解 编辑:程序博客网 时间:2024/05/10 15:11

今天下午加半个晚上终于对照着lkx的代码学会splay了。。明天巩固一下再写点题。。

话说lkx的代码真是凝练,看的就很享受,话说我学splay学了快三个小时

智商真是硬伤。。。

不管怎么说还是写出来了hnoi2002的营业额统计,明天写hnoi2004的题

下面是代码

#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#define MAX 35000+9using 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);    } }elserotate(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;}