【題解】 P2234 [HNOI2002]營業額統計
阿新 • • 發佈:2018-11-14
平衡樹板題
原題傳送門
這道題要用Splay,我部落格裡有對Splay的詳細介紹
這道題目還算比較模板的
每輸入一個數,先不要插入
要求一下前驅和後繼與x差的最小值並加到答案中
再把x插入平衡樹
然後你會發現過不了樣例
發現相同的數字是會有的
所以還要寫find函式,要多加一個變數來比最小:
find(x)!=0?0:inf;
剩下就沒什麼問題了qaq
#pragma GCC optimize("O3") #include <bits/stdc++.h> #define root tree[0].ch[1] #define inf 1000000005 using namespace std; inline int read() { register int x=0,f=1;register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f; } inline int Min(register int a,register int b) { return a<b?a:b; } struct Splay{ int fa,ch[2],sum,rec,v; }tree[32780]; int tot=0; inline bool findd(register int x) { return x==tree[tree[x].fa].ch[0]?0:1; } inline void connect(register int x,register int fa,register int son) { tree[x].fa=fa; tree[fa].ch[son]=x; } inline void update(register int x) { tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec; } inline void rotate(register int x) { int Y=tree[x].fa; int R=tree[Y].fa; int Yson=findd(x); int Rson=findd(Y); int B=tree[x].ch[Yson^1]; connect(B,Y,Yson); connect(Y,x,Yson^1); connect(x,R,Rson); update(Y),update(x); } inline void splay(register int x,register int to) { to=tree[to].fa; while(tree[x].fa!=to) { int y=tree[x].fa; if(tree[y].fa==to) rotate(x); else if(findd(x)==findd(y)) rotate(y),rotate(x); else rotate(x),rotate(x); } } inline int newpoint(register int v,register int fa) { tree[++tot].v=v; tree[tot].fa=fa; tree[tot].sum=tree[tot].rec=1; return tot; } inline void Insert(register int x) { int now=root; if(root==0) { newpoint(x,0); root=tot; } else { while(19260817) { ++tree[now].sum; if(x==tree[now].v) { ++tree[now].rec; splay(now,root); return; } int nxt=x<tree[now].v?0:1; if(!tree[now].ch[nxt]) { int p=newpoint(x,now); tree[now].ch[nxt]=p; splay(p,root); return; } now=tree[now].ch[nxt]; } } } inline int find(register int v) { int now=root; while(19260817) { if(tree[now].v==v) { splay(now,root); return now; } int nxt=v<tree[now].v?0:1; if(!tree[now].ch[nxt]) return 0; now=tree[now].ch[nxt]; } } inline int lower(register int v) { int now=root; int ans=-inf; while(now) { if(tree[now].v<v&&tree[now].v>ans) ans=tree[now].v; if(v>tree[now].v) now=tree[now].ch[1]; else now=tree[now].ch[0]; } return ans; } inline int upper(register int v) { int now=root; int ans=inf; while(now) { if(tree[now].v>v&&tree[now].v<ans) ans=tree[now].v; if(v<tree[now].v) now=tree[now].ch[0]; else now=tree[now].ch[1]; } return ans; } int main() { int n=read(); int res=0; for(register int i=1;i<=n;++i) { int x=read(); if(i==1) res=x; else res+=Min(Min(fabs(lower(x)-x),fabs(upper(x)-x)),find(x)!=0?0:inf); Insert(x); } printf("%d",res); return 0; }