「HNOI2002」营业额统计 发表于 2019-04-07 | 分类于 平衡树 | | 浏览量: 次 裸的平衡树? 题解我们需要求出每一天营业额的前驱和后继,然后挑一个更接近的就行了。 直接上平衡树搞就行。 或者调用STL里的set。 代码蒟蒻我手写了个伸展树。 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091#include<cstdio>#include<algorithm>using namespace std;const int maxn=32800,inf=0X3F3F3F3F;int n,ans;bool vis[2000010];inline int read(){ int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();} return ret*f;}struct SplayTree{ int tot,root; struct Node{int val,siz,fa,son[2];}Tree[maxn]; inline int check(int x){return Tree[Tree[x].fa].son[1]==x?1:0;} inline void PushUp(int x){Tree[x].siz=Tree[Tree[x].son[0]].siz+Tree[Tree[x].son[1]].siz+1;} inline void Rotate(int x) { int y=Tree[x].fa,z=Tree[y].fa,k=check(x),w=Tree[x].son[k^1]; Tree[y].son[k]=w; Tree[w].fa=y; Tree[x].fa=z; Tree[z].son[check(y)]=x; Tree[x].son[k^1]=y; Tree[y].fa=x; PushUp(y); PushUp(x); } inline void Splay(int x) { while(Tree[x].fa) { int y=Tree[x].fa; if(Tree[y].fa) { if(check(x)==check(y)) Rotate(y); else Rotate(x); } Rotate(x); } root=x; } inline void Insert(int v) { int p=root,fa=0; while(p) { fa=p; p=Tree[p].son[v>Tree[p].val]; } p=++tot; Tree[fa].son[v>Tree[fa].val]=p; Tree[p].fa=fa; Tree[p].siz=1; Tree[p].val=v; Splay(p); } int FindPre(int v) { int p=Tree[root].son[0]; if(!p) return -inf; while(Tree[p].son[1]) p=Tree[p].son[1]; return Tree[p].val; } int FindSuf(int v) { int p=Tree[root].son[1]; if(!p) return inf; while(Tree[p].son[0]) p=Tree[p].son[0]; return Tree[p].val; }}ST;int main(){ n=read(); for(int i=1;i<=n;i++) { int Ai=read(); if(i==1) ans+=Ai; if(!vis[Ai+1000005]) { ST.Insert(Ai); if(i!=1) ans+=min(Ai-ST.FindPre(Ai),ST.FindSuf(Ai)-Ai); vis[Ai+1000005]=true; } } printf("%d\n",ans); return 0;}