zoukankan      html  css  js  c++  java
  • 伸展树

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define maxn 110000
    #define INF 99999999
    struct splaytree
    {
        int pre[maxn];
        int key[maxn];
        int ch[maxn][2];
        int root,tot;
        void init()
        {
            tot=root=0;
            memset(ch,0,sizeof(ch));
            memset(pre,0,sizeof(pre));
            memset(key,0,sizeof(key));
        }
        void newnode(int &r,int father,int k)
        {
            r=++tot;
            pre[r]=father;
            key[r]=k;
            ch[r][0]=ch[r][1]=0;
        }
        void rot(int x,int kind)//zuo haizi  you xuan
        {
            int y=pre[x];//待伸展点的前驱
            ch[y][!kind]=ch[x][kind];//待伸展点与旋转方向相同的子节点赋值给待伸展点父节点的待伸展点方向作为孩子 
            pre[ch[x][kind]]=y;//原待伸展节点伸展方向的子节点前驱改为待伸展节点的父节点 
            ch[x][kind]=y;//待伸展点父节点赋值给待伸展点旋转方向作为子节点
            //以上3步完成待伸展节点子节点、待伸展节点父节点的移动 
            if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;//原待伸展点前驱的前驱的子节点更改为待伸展点
            pre[x]=pre[y];//待伸展点的前驱改为原待伸展点前驱的前驱
            pre[y]=x;//原待伸展点的前驱改为待伸展点 
             
        }
        void splay(int x,int goal)
        {
            while(pre[x]!=goal)
            {
                if(pre[pre[x]]==goal) rot(x,ch[pre[x]][0]==x);
                else
                {
                    int y=pre[x];//待伸展点的前驱
                    int kind=ch[pre[y]][0]==y; //待伸展点前驱的前驱的左孩子是否是待伸展点的前驱,是为1
                    if(ch[y][kind]==x)
                    {
                        rot(x,!kind);
                        rot(x,kind);
                    } 
                    else
                    {
                        rot(y,kind);
                        rot(x,kind);
                    }
                } 
            }
            if(goal==0) root=x;
        }
        int insert(int x)
        {
            int r=root;
            while(ch[r][key[r]<x])//0 zuo  1 you
            {
                if(key[r]==x)
                {
                    splay(r,0);
                    return 0;
                }
                r=ch[r][key[r]<x];
            }
            newnode(ch[r][key[r]<x],r,x);
            splay(ch[r][key[r]<x],0);
            return 1;
        }
        int get_pre(int x)
        {
            int r=ch[x][0];
            if(r==0) return -INF;
            while(ch[r][1]) r=ch[r][1];
            return key[r];
        }
        int get_next(int x)
        {
            int r=ch[x][1];
            if(r==0) return INF;
            while(ch[r][0]) r=ch[r][0];
            return key[r];
        }
    }tree;
    int main()
    {
        int n,i;
        scanf("%d",&n);
        int sum=0;
        int x;
        tree.init();
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(i==1)
            {
                sum+=x;
                tree.newnode(tree.root,0,x);
                continue;
            }
            if(tree.insert(x)==0) continue;
            int a=tree.get_pre(tree.root);
            int b=tree.get_next(tree.root); 
            sum+=min(x-a,b-x);
        }
        printf("%d
    ",sum);
    }
  • 相关阅读:
    C# List<T>用法(转)
    任务列表 (Visual Studio)
    TSQL行转列、列转行
    HRESULT:0x80070057 (E_INVALIDARG)的异常的解决方案(转)
    JS正则表达式详解(转)
    Windows远程登录命令
    JavaScript中的try...catch和异常处理(转)
    javascript如何触发button 的click事件
    在ASP.NET中利JavaScript实现控件的聚焦(转)
    输入一个字符串,将其逆序后输出。(使用C++,不建议用伪码)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6287819.html
Copyright © 2011-2022 走看看