标签:
第一道splay,算是学会了最最基础的splay操作。
有一点要特别注意,就是一字型旋转的时候要先旋转y再旋x,这样复杂度降低很多。。。不要写成两次都旋转x。。。
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; struct Splay { int key[maxn]; int pre[maxn]; int ch[maxn][2]; int rt,tot; void newnode(int &r,int fa,int k) { r=++tot; key[r]=k; pre[r]=fa; ch[r][0]=ch[r][1]=0; } void rot(int x,int op) { int y=pre[x]; ch[y][op^1]=ch[x][op]; pre[ch[x][op]]=y; if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; ch[x][op]=y; pre[y]=x; } void splay(int x,int goal) { while(pre[x]!=goal){ if(pre[pre[x]]==goal) rot(x,ch[pre[x]][0]==x); else{ int y=pre[x]; int op=ch[pre[y]][0]==y; if(ch[y][op]==x) rot(x,op^1),rot(x,op); else rot(y,op),rot(x,op); } } if(goal==0) rt=x; } int insert(int k) { int u=rt; while(ch[u][k>key[u]]){ if(k==key[u]){ splay(u,0); return 0; } u=ch[u][k>key[u]]; } newnode(ch[u][k>key[u]],u,k); splay(ch[u][k>key[u]],0); return 1; } void init() { MS0(pre); tot=0; newnode(rt,0,-INF); insert(INF); } int get_pre(int x) { int u=ch[x][0]; while(ch[u][1]) u=ch[u][1]; return key[u]; } int get_next(int x) { int u=ch[x][1]; while(ch[u][0]) u=ch[u][0]; return key[u]; } };Splay tree; int n,a[maxn]; int main() { freopen("in.txt","r",stdin); while(cin>>n){ tree.init(); int ans=0; REP(i,1,n){ scanf("%d",&a[i]); if(!tree.insert(a[i])) continue; int tmp=0; if(i==1) tmp=a[i]; else{ int x=tree.get_pre(tree.rt); int y=tree.get_next(tree.rt); tmp=min(abs(x-a[i]),abs(y-a[i])); //cout<<x<<" "<<y<<" "<<a[i]<<endl; } ans+=tmp; } cout<<ans<<endl; } return 0; }
标签:
原文地址:http://www.cnblogs.com/--560/p/5197606.html