• 查找前驱后继 方法小结


    例题:HNOI2012 营业额统计

     

    题目大意:

    设排完序后,x的前驱为a,后继为b,求 Σ min(x-a,b-x)

    法一:双向链表 64ms 1MB

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,rank[40000],pos,ans;
    struct node
    {
        int id,w;
        int l,r;
    }e[40000];
    bool cmp(node p,node q)
    {
        return p.w<q.w;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&e[i].w),e[i].id=i;
        sort(e+1,e+n+1,cmp);
        for(int i=1;i<=n;i++) e[i].l=i-1,e[i].r=i+1;
        e[n].r=0;e[0].w=-1e9;
        for(int i=1;i<=n;i++) rank[e[i].id]=i;
        for(int i=n;i>=1;i--)
        {
            pos=rank[i];
            if(e[pos].l&&e[pos].r) ans+=min(e[pos].w-e[e[pos].l].w,e[e[pos].r].w-e[pos].w);
            else if(e[pos].l) ans+=e[pos].w-e[e[pos].l].w;
            else if(e[pos].r) ans+=e[e[pos].r].w-e[pos].w;
            else ans+=e[pos].w;
            e[e[pos].r].l=e[pos].l;
            e[e[pos].l].r=e[pos].r;
        }
        printf("%d",ans);
    }
    View Code

    法二:set  101ms 1MB

    #include<cstdio>
    #include<set>
    #include<algorithm>
    using namespace std;
    set<int>s;
    int n,x,tmp,l,r,mid,w,k;
    int ans;
    int main()
    {
        scanf("%d",&n);
        scanf("%d",&x);
        s.insert(x);
        ans+=x; 
        for(int i=1;i<n;i++)
        {
            scanf("%d",&x);
            set<int>::iterator a=s.lower_bound(x);
            set<int>::iterator b=a;
            if(a!=s.begin()) a--;
            if(b==s.end()) b--;
            ans+=min(abs(x-*a),abs(*b-x));
            s.insert(x);
        }
        printf("%d",ans);
    }
    View Code

    法三:splay 90ms 1004KB

    #include<cstdio>
    #include<algorithm>
    #define N 32770
    #define INF 2000000
    using namespace std;
    int root,ans;
    class splay_tree
    {
        private:
            int pre[N],ch[N][2],key[N],tot;
        public:
            inline void newnode(int &r,int fa,int k)
            {
                r=++tot;
                pre[r]=fa;
                key[r]=k;
            }
            inline void rot(int x,int kind)
            {
                int y=pre[x];
                ch[y][!kind]=ch[x][kind];
                pre[ch[x][kind]]=y;
                ch[x][kind]=y;
                if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
                pre[x]=pre[y];
                pre[y]=x;
            }
            inline void splay(int x,int goal)
            {            
                while(pre[x]!=goal)
                {
                    int y=pre[x];
                    int kind=ch[y][0]==x;
                    if(pre[y]==goal) rot(x,kind);
                    else
                    {
                        kind=ch[pre[y]][0]==y;
                        if(ch[y][!kind]==x)
                        {                        
                            rot(y,kind);
                            rot(x,kind);
                        }
                        else
                        {
                            rot(x,!kind);
                            rot(x,kind);
                        }
                    }
                }
                root=x;
            }
            inline int insert(int x)
            {
                int r=root;
                while(ch[r][x>key[r]]) 
                {
                    if(x==key[r]) {splay(r,0);return 0;}
                    r=ch[r][x>key[r]];
                }
                if(x==key[r]) {splay(r,0);return 0;}
                newnode(ch[r][x>key[r]],r,x);
                splay(ch[r][x>key[r]],0);
                return 1;
            }
            inline int get_pre(int x)
            {
                int r=ch[x][0];
                if(!r) return -INF;
                while(ch[r][1]) r=ch[r][1];
                return key[r];
            }
            inline int get_suf(int x)
            {
                int r=ch[x][1];
                if(!r) return INF;
                while(ch[r][0]) r=ch[r][0];
                return key[r];
            }
            
    }tree;
    int main()
    {
        int n,x;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(i==1)
            {
                ans+=x;
                tree.newnode(root,0,x);
            }
            else
            {
                if(!tree.insert(x)) continue;
                int a=tree.get_pre(root);
                int b=tree.get_suf(root);
                ans+=min(x-a,b-x);
            }    
        }
        printf("%d",ans);
    }
    View Code
  • 相关阅读:
    Redis 如何设置密码及验证密码?
    怎么测试 Redis 的连通性?
    Redis 的内存用完了会发生什么?
    假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以 某个固定的已知的前缀开头的,如果将它们全部找出来?
    使用过 Redis 做异步队列么,你是怎么用的?
    简述在 MySQL 数据库中 MyISAM 和 InnoDB 的区别 ?
    你怎么看到为表格定义的所有索引?
    深入理解卷积网络的卷积
    OpenCV-Python 图像阈值 | 十五
    OpenCV-Python 图像的几何变换 | 十四
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6707125.html
Copyright © 2020-2023  润新知