• [HNOI2002]营业额统计


    http://61.187.179.132/JudgeOnline/problem.php?id=1588

    splay,一种功能超级强大的数据结构,且较易实现,核心操作是旋转

    求前驱后继

    #include <iostream>
    #include <cstdio>
    using namespace std ; 
    const int maxn=100005 ;
    const int INF=0xfffffff ;
    int son[maxn][2],fa[maxn],key[maxn] ;
    int rt,size ;
    void link(int x,int y,int k)//将x连到y的k儿子上 0左1右 
    {
        fa[x]=y ;
        son[y][k]=x ;
    }
    void rotate(int x,int k)//k=0 x是y的lson 单旋转 
    {
        int y=fa[x] ;
        link(x,fa[y],son[fa[y]][1]==y) ;
        link(son[x][!k],y,k) ;
        link(y,x,!k) ;
    }
    void splay(int x,int g)
    {
        while(fa[x]!=g)
        {
            int y=fa[x],sx=(son[y][1]==x),sy=(son[fa[y]][1]==y) ;
            if(fa[y]==g)
                rotate(x,sx) ;
            else
            {
                if(sx==sy)        //zig-zig || zag-zag
                    rotate(y,sx) ;
                else              //zig-zag || zag-zig 
                    rotate(x,sx) ;
                rotate(x,sy) ;
            }
        }
        if(!g)rt=x ;
    }
    void newnode(int y,int &x,int a)
    {
        x=++size ;
        fa[x]=y ;key[x]=a ;
        son[x][0]=son[x][1]=0 ;
    }
    void insert(int a)
    {
        int x=rt ;
        while(son[x][key[x]<a])
            x=son[x][key[x]<a] ;
        newnode(x,son[x][key[x]<a],a) ;
        splay(size,0) ;
    }
    int pre(int a)//前驱 <=a的最大数 
    {
        int x=rt,ans=-INF ;
        while(x)
        {
            if(key[x]==a)
                return a ;
            if(key[x]<a)
                ans=max(ans,key[x]) ;
            x=son[x][key[x]<a] ;
        }
        return ans ;
    }
    int suc(int a)//后继 >=a的最小数 
    {
        int x=rt,ans=INF ;
        while(x)
        {
            if(key[x]==a)
                return a ;
            if(key[x]>a)
                ans=min(ans,key[x]) ;
            x=son[x][key[x]<a] ;
        }
        return ans ;
    }
    int n,a,ans ;
    int main()
    {
        scanf("%d%d",&n,&a) ;
        ans=a ;
        insert(a) ;
        while(--n)
        {
            if(scanf("%d",&a)==EOF)
                a=0 ;
            ans+=min(a-pre(a),suc(a)-a) ;
            insert(a) ;
        }
        printf("%d
    ",ans) ;
        return 0 ;
    }
    View Code
  • 相关阅读:
    HDU 1982 Kaitou Kid The Phantom Thief (1)
    HDU 1984 Mispelling4
    HDU 2546 饭卡
    HDU 1009 FatMouse' Trade
    在VC 中如何隐藏一个主程序窗口
    .菜单项
    SetClassLong,GetClassLong 动态改变光标
    .窗口捕获鼠标
    .主窗口向子控件发送消息
    线段树 1698 Just a Hook 区间set更新
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/3492902.html
Copyright © 2020-2023  润新知