bzoj1588 [HNOI2002]营业额统计(treap)

treap就是tree+heap。每个节点有一个值v,还有一个优先级rnd.从v来看,这是一棵bst,从rnd来看,这是一个小根堆。维护好这两个性质即可。

#include 
#include 
#include 
#include 
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 40010
inline char gc(){
    static char buf[1<<16],*S,*T;
    if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x*f;
}
int n,ls[N],rs[N],sz[N],rt=0,ans=0,cnt[N],v[N],rnd[N],owo=0;
inline void update(int p){
    sz[p]=sz[ls[p]]+sz[rs[p]]+cnt[p];
}
inline void rturn(int &y){int x=ls[y];ls[y]=rs[x];rs[x]=y;update(y);update(x);y=x;}
inline void lturn(int &y){int x=rs[y];rs[y]=ls[x];ls[x]=y;update(y);update(x);y=x;}
inline void ins(int &p,int x){
    if(!p){p=++owo;sz[p]=cnt[p]=1;v[p]=x;rnd[p]=rand();return;}
    if(v[p]==x){cnt[p]++;sz[p]++;return;}
    if(xif(rnd[ls[p]]else {ins(rs[p],x);if(rnd[rs[p]]inline int pre(int x){
    int res=-inf,p=rt;
    while(p){
        if(v[p]==x){res=v[p];break;}
        if(v[p]else p=ls[p];
    }return res;
}
inline int succ(int x){
    int res=inf,p=rt;
    while(p){
        if(v[p]==x){res=v[p];break;}
        if(v[p]>x) res=v[p],p=ls[p];
        else p=rs[p];
    }return res;
}
int main(){
//  freopen("a.in","r",stdin);
    srand(20000712);n=read();
    for(int i=1;i<=n;++i){
        int x=read();
        if(i==1) ans+=x;
        else ans+=min(x-pre(x),succ(x)-x);ins(rt,x);
    }printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(bzoj,平衡树)