1. 程式人生 > >BZOJ1588: [HNOI2002]營業額統計

BZOJ1588: [HNOI2002]營業額統計

clu namespace targe nds ota roo text bsp noi2002

【傳送門:BZOJ1588】


簡要題意:

  給出n個數,每個數只能前面的任意一個數相減,要求差的絕對值最小,求出所有數做的差的最小絕對值的和(第一個數做得差的最小絕對值就是它自己)


題解:

  伸展樹SPLAY,將n個數逐個放進伸展樹中,在放一個數時,先求出這個數在樹中的前驅和後繼,然後比較哪個最接近這個數,然後ans加上前驅或後繼與這個數的差的絕對值,然後把這個數放進伸展樹裏


參考代碼:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include
<cmath> using namespace std; struct node { int n,d,f,c,son[2]; }a[110000];int len,root; void add(int d,int f) { len++; a[len].d=d;a[len].c=a[len].n=1; a[len].son[1]=a[len].son[0]=0;a[len].f=f; if(d<a[f].d) a[f].son[0]=len; else a[f].son[1]=len; }
void update(int x) { int lc=a[x].son[0],rc=a[x].son[1]; a[x].c=a[x].n+a[lc].c+a[rc].c; } int findip(int d) { int x=root; while(a[x].d!=d) { if(a[x].d>d) { if(a[x].son[0]==0)break; else x=a[x].son[0]; } else {
if(a[x].son[1]==0)break; else x=a[x].son[1]; } } return x; } void rotate(int x,int w) { int f=a[x].f,ff=a[f].f; int r,R; r=a[x].son[w];R=f; a[R].son[1-w]=r; if(r!=0)a[r].f=R; r=x;R=ff; if(a[R].son[0]==f)a[R].son[0]=r; else a[R].son[1]=r; a[r].f=R; r=f;R=x; a[R].son[w]=r; a[r].f=R; update(f); update(x); } void splay(int x,int rt) { while(a[x].f!=rt) { int f=a[x].f,ff=a[f].f; if(ff==rt) { if(a[f].son[0]==x)rotate(x,1); else rotate(x,0); } else { if(a[f].son[0]==x && a[ff].son[0]==f){rotate(f,1);rotate(x,1);} else if(a[f].son[1]==x && a[ff].son[0]==f){rotate(x,0);rotate(x,1);} else if(a[f].son[0]==x && a[ff].son[1]==f){rotate(x,1);rotate(x,0);} else if(a[f].son[1]==x && a[ff].son[1]==f){rotate(f,0);rotate(x,0);} } } if(rt==0)root=x; } void ins(int d) { if(root==0) { add(d,0);root=len; return ; } int x=findip(d); if(d==a[x].d) { a[x].n++; update(x); splay(x,0); } else { add(d,x); update(x); splay(len,0); } } void del(int d) { int x=findip(d);splay(x,0); if(d!=a[x].d)return ; if(a[x].n>1){a[x].n--;update(x);return ;} if(a[x].son[0]==0 && a[x].son[1]==0){root=0;len=0;} else if(a[x].son[0]!=0 && a[x].son[1]==0){root=a[x].son[0];a[root].f=0;} else if(a[x].son[1]!=0 && a[x].son[0]==0){root=a[x].son[1];a[root].f=0;} else { int p=a[x].son[0]; while(a[p].son[1]!=0)p=a[p].son[1]; splay(p,x); int r,R; r=a[x].son[1];R=p; a[R].son[1]=r; a[r].f=R; root=R;a[root].f=0; update(R); } } int findqianqu(int d) { int x=findip(d);splay(x,0); if(d<a[x].d && a[x].son[0]!=0) { x=a[x].son[0]; while(a[x].son[1]!=0)x=a[x].son[1]; } if(d<a[x].d)x=0; return x; } int findhouji(int d) { int x=findip(d);splay(x,0); if(d>a[x].d && a[x].son[1]!=0) { x=a[x].son[1]; while(a[x].son[0]!=0)x=a[x].son[0]; } if(d>a[x].d)x=0; return x; } int findpaiming(int d) { int x=findip(d); splay(x,0); return a[a[x].son[0]].c+1; } int findshuzi(int k) { int x=root; while(1) { int lc=a[x].son[0],rc=a[x].son[1]; if(k<=a[lc].c)x=lc; else if(k>a[lc].c+a[x].n){k-=a[lc].c+a[x].n;x=rc;} else break; } return a[x].d; } int n; int main() { scanf("%d",&n);len=0;root=0; int ans=0;int d; scanf("%d",&d);ans+=d;ins(d); for(int i=2;i<=n;i++) { scanf("%d",&d); int ss=999999999; int lc=findqianqu(d),rc=findhouji(d); if(lc!=0) ss=abs(a[lc].d-d); if(rc!=0) ss=min(abs(a[rc].d-d),ss); ans+=ss; ins(d); } printf("%d\n",ans); return 0; }

BZOJ1588: [HNOI2002]營業額統計