[HNOI2002]营业额统计
treap板子题。
前驱后继查询。
代码:
#include<ctime> #include<cstdio> #include<cstdlib> using namespace std; #define N 33000 int n,a; int rt,tot; struct Treap { int ls,rs; int siz,w,rnd,v; }tr[N]; void update(int u) { tr[u].siz = tr[tr[u].ls].siz + tr[tr[u].rs].siz + tr[u].w; } void lturn(int &x) { int y = tr[x].rs; tr[x].rs = tr[y].ls; tr[y].ls = x; tr[y].siz = tr[x].siz; update(x); x=y; } void rturn(int &x) { int y = tr[x].ls; tr[x].ls = tr[y].rs; tr[y].rs = x; tr[y].siz = tr[x].siz; update(x); x=y; } void insert(int &k,int x) { if(!k) { k = ++tot; tr[k].siz = tr[k].w = 1; tr[k].v = x,tr[k].rnd = rand(); return ; } tr[k].siz++; if(tr[k].v==x) { tr[k].w++; return ; }else if(tr[k].v<x) { insert(tr[k].rs,x); if(tr[tr[k].rs].rnd<tr[k].rnd)lturn(k); }else { insert(tr[k].ls,x); if(tr[tr[k].ls].rnd<tr[k].rnd)rturn(k); } } int ans = 0; void qq(int u,int x) { if(!u)return ; if(tr[u].v<=x) { ans = tr[u].v; qq(tr[u].rs,x); }else qq(tr[u].ls,x); } void hj(int u,int x) { if(!u)return ; if(tr[u].v>=x) { ans = tr[u].v; hj(tr[u].ls,x); }else hj(tr[u].rs,x); } int main() { srand(time(NULL)); scanf("%d",&n); int as = 0; insert(rt,-2000005); insert(rt,2000005); for(int i=1;i<=n;i++) { scanf("%d",&a); if(i==1) { insert(rt,a); as+=a; continue; } ans = -2000005; qq(rt,a); int tmp = a-ans; ans = 2000005; hj(rt,a); tmp = tmp<(ans-a)?tmp:(ans-a); as+=tmp; insert(rt,a); } printf("%d\n",as); return 0; }