bzoj1588

0 篇文章 0 订阅
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<vector>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=4e5+10,INF=1<<30;
struct Node
{
    int v,sz;
    Node *fa,*ch[2];
    Node(int v=0):v(v){sz=1;ch[0]=ch[1]=fa=NULL;}
    int cmp(int x) {return x==v?-1:x>v;}
    void up() {
        sz=1;
        if(ch[0]!=NULL) sz+=ch[0]->sz;
        if(ch[1]!=NULL) sz+=ch[1]->sz;
    }
}*pool[N*2];
int top=0,n;
void init() {for(int i=0;i<N;i++) pool[i]=new Node();}
void newnode(Node* &p,int v,Node *fa){p=pool[top++]; *p=Node(v); p->fa=fa;}
void del(Node* &p) {pool[--top]=p;p=NULL;}
struct SplayTree{
    Node *root;
    inline int pd(Node *p){return p->fa->ch[1]==p;}
    inline void rotate(Node* p)
    {
        int c=pd(p)^1;Node *t=p->fa;
        t->ch[c^1]=p->ch[c];
        if(p->ch[c])p->ch[c]->fa=t;
        if((p->fa=t->fa)!=NULL) p->fa->ch[p->fa->ch[1]==t]=p;
        t->fa=p;p->ch[c]=t;t->up();p->up();
        if(p->fa==NULL) root=p;
    }
    inline void splay(Node* p,Node *FA)
    {
        for(;p->fa!=FA;rotate(p))
            if(p->fa->fa!=FA) rotate(pd(p)==pd(p->fa)?p->fa:p);
    }
    void insert(Node* p,int val)
    {
        if(root==NULL){newnode(root,val,NULL);return ;}
        Node *fa=NULL;
        while(p!=NULL) fa=p,p=p->ch[val > p->v];
        newnode(p,val,fa);fa->ch[val>fa->v]=p;
        for(fa=p->fa;fa!=NULL;fa=fa->fa) 
            fa->up();
        splay(p,NULL);
    }
    inline Node* find(Node *p,int val)
    {
        while(p!=NULL) {
            int tcmp=p->cmp(val);
            if(tcmp==-1) return p;
            p=p->ch[tcmp];
        }
        return NULL;
    }
    Node* MAX(Node* p){
        if(p==NULL) return NULL;
        while(p->ch[1]!=NULL) p=p->ch[1];
        return p;
    } 
    Node* merge(Node* a,Node* b)
    {
        if(!b) return a;
        if(!a) return b;
        Node *t=MAX(a);
        splay(t,NULL);
        t->ch[1]=b;b->fa=t;t->up();
        return t;
    }
    void remove(Node* p,int val)
    {
        Node* pos=find(root,val);
        splay(pos,NULL);
        pos=root;del(root);
        root=merge(pos->ch[0],pos->ch[1]);
        if(root!=NULL)root->fa=NULL;
    }
    inline int rank(Node* p,int val)
    {
        int ret=1;
        while(p!=NULL){
            int tcmp=val > p->v,d=p->ch[0]?p->ch[0]->sz:0;
            if(tcmp) ret+=d+1; p=p->ch[tcmp];
        }
        return ret;
    }
    inline int kth(Node* p,int k)
    {
        while(p!=NULL){
            int d=p->ch[0]?p->ch[0]->sz:0;
            if(k==d+1) return p->v;
            if(k<d+1) p=p->ch[0];
            else k-=d+1,p=p->ch[1];
        }
        return -1;
    }
    inline int Pre(Node* p,int val)
    {
        int ret=-INF;
        while(p!=NULL){
            int tcmp=val > p->v;
            if(tcmp) ret=max(ret,p->v);
            p=p->ch[tcmp];
        }
        return ret;
    }
    inline int Sub(Node* p,int val)
    {
        int ret=INF;
        while(p!=NULL){
            int tcmp=val < p->v;
            if(tcmp) ret=min(ret,p->v);
            p=p->ch[tcmp^1];
        }
        return ret;
    }
    inline void insert(int x){insert(root,x);}
    inline void remove(int x){remove(root,x);}
    inline int rank(int x){return rank(root,x);}
    inline int kth(int x){return kth(root,x);}
    inline int Pre(int x){return Pre(root,x);}
    inline int Sub(int x){return Sub(root,x);}
}splay;
int a[N],vis[1000000+10];
int main()
{
    init();
    memset(vis,0,sizeof(vis));
    scanf("%d",&n);
    long long ans=0;
    scanf("%d",&a[1]);
    splay.insert(a[1]);
    ans+=a[1];
    vis[a[1]]=1;
    for(int i=2;i<=n;i++) {
        scanf("%d",&a[i]);
        if(!vis[a[i]]) {ans+=min(a[i]-splay.Pre(a[i]),splay.Sub(a[i])-a[i]);vis[a[i]]=1;}
        splay.insert(a[i]);
    }
    printf("%lld\n",ans);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值