BZOJ 1588 [HNOI2002]营业额统计

来源:互联网 发布:奥威软件 编辑:程序博客网 时间:2024/06/06 05:49

splay。

模仿别人的代码打的,加了一些注释

我很好奇排名第一的0s用了什么神奇的数结- -

#include<cstdio>#include<cmath>#include<algorithm>#define N 200005using namespace std;const int INF = 1<<29;struct SplayTree{    int son[N][2], fa[N], siz[N], cnt[N], val[N], root, tot;    void up(int x)    {        siz[x]=siz[son[x][0]]+siz[son[x][1]]+cnt[x];    }    void rotate(int x, int flag)//flag 0左旋 1右旋    {        int y=fa[x];        //分步处理,都是两行,一个改fa一个改son         //1.处理x的儿子         son[y][flag^1]=son[x][flag];        fa[son[x][flag]]=y;        //2.处理y的父亲         fa[x]=fa[y];        if(fa[y])son[fa[y]][son[fa[y]][1]==y]=x;                //3.处理x和y         fa[y]=x;        son[x][flag]=y;         up(y);    }     void splay(int x, int goal)//将x旋到goal之下,goal=0表示x转为根     {        while(fa[x]!=goal)        {            if(fa[fa[x]]==goal)//单旋                 rotate(x,son[fa[x]][0]==x);            else            {                int fax=fa[x], faxx=fa[fax], flag=(son[faxx][0]==fax);                if(son[x][flag]==x)//双左右旋,双右左旋                 {                    rotate(x,!flag);                    rotate(x,flag);                }                 else//双左左旋,双右右旋                 {                    rotate(fax,flag); //父亲单旋,以降低层数                     rotate(x,flag);                }            }        }         up(x);        if(goal==0)            root=x;    }     void add_node(int v, int fat)     {        val[++tot]=v;        son[tot][1]=son[tot][0]=0;        fa[tot]=fat;        son[fat][val[fat]<v]=tot;        cnt[tot]=siz[tot]=1;    }    void init()    {        tot=0;        root=1;        add_node(INF,0);//实际上是一号节点         add_node(-1*INF,1); //实际上是二号节点        //加入最值保证查找不出错         siz[1]=1;    }    void inser(int pre, int fat, int v)    {        if(!pre)        {            add_node(v,fat);            splay(tot,0);            return;        }        if(val[pre]==v)        {            cnt[pre]++;            up(pre);            splay(pre,0);            return;        }        if(v>val[pre])inser(son[pre][1],pre,v);        else inser(son[pre][0],pre,v);        up(pre);    }       void find_max(int &x, int pre, int v)    {        if(!pre)return;        if(v<=val[pre])        {            x=val[pre];            find_max(x,son[pre][0],v);        }        else            find_max(x,son[pre][1],v);    }    void find_min(int &x, int pre, int v)    {        if(!pre)return;        if(v>val[pre])        {            x=val[pre];            find_min(x,son[pre][1],v);        }        else            find_min(x,son[pre][0],v);    }}st;int main(){    int n, a;    st.init();    scanf("%d",&n);    scanf("%d",&a);    st.inser(st.root,0,a);    int ans=a;    for(int i = 1; i < n; i++)    {        int pre1, pre2, now;        scanf("%d",&a);        st.find_max(pre1,st.root,a);        st.find_min(pre2,st.root,a);        now=min(abs(pre2-a),abs(pre1-a));        ans+=now;        st.inser(st.root,0,a);     }    printf("%d\n",ans);}
1 0
原创粉丝点击