zoukankan      html  css  js  c++  java
  • BZOJ1588: [HNOI2002]营业额统计

    【传送门:BZOJ1588


    简要题意:

      给出n个数,每个数只能前面的任意一个数相减,要求差的绝对值最小,求出所有数做的差的最小绝对值的和(第一个数做得差的最小绝对值就是它自己)


    题解:

      伸展树SPLAY,将n个数逐个放进伸展树中,在放一个数时,先求出这个数在树中的前驱和后继,然后比较哪个最接近这个数,然后ans加上前驱或后继与这个数的差的绝对值,然后把这个数放进伸展树里


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    struct node
    {
        int n,d,f,c,son[2];
    }a[110000];int len,root;
    void add(int d,int f)
    {
        len++;
        a[len].d=d;a[len].c=a[len].n=1;
        a[len].son[1]=a[len].son[0]=0;a[len].f=f;
        if(d<a[f].d)
            a[f].son[0]=len;
        else
            a[f].son[1]=len;
    }
    void update(int x)
    {
        int lc=a[x].son[0],rc=a[x].son[1];
        a[x].c=a[x].n+a[lc].c+a[rc].c;
    }
    int findip(int d)
    {
        int x=root;
        while(a[x].d!=d)
        {
            if(a[x].d>d)
            {
                if(a[x].son[0]==0)break;
                else x=a[x].son[0];
            }
            else
            {
                if(a[x].son[1]==0)break;
                else x=a[x].son[1];
            }
        }
        return x;
    }
    void rotate(int x,int w)
    {
        int f=a[x].f,ff=a[f].f;
        int r,R;
        
        r=a[x].son[w];R=f;
        a[R].son[1-w]=r;
        if(r!=0)a[r].f=R;
        
        r=x;R=ff;
        if(a[R].son[0]==f)a[R].son[0]=r;
        else a[R].son[1]=r;
        a[r].f=R;
        
        r=f;R=x;
        a[R].son[w]=r;
        a[r].f=R;
        
        update(f);
        update(x);
    }
    void splay(int x,int rt)
    {
        while(a[x].f!=rt)
        {
            int f=a[x].f,ff=a[f].f;
            if(ff==rt)
            {
                if(a[f].son[0]==x)rotate(x,1);
                else rotate(x,0);
            }
            else
            {
                     if(a[f].son[0]==x && a[ff].son[0]==f){rotate(f,1);rotate(x,1);}
                else if(a[f].son[1]==x && a[ff].son[0]==f){rotate(x,0);rotate(x,1);}
                else if(a[f].son[0]==x && a[ff].son[1]==f){rotate(x,1);rotate(x,0);}
                else if(a[f].son[1]==x && a[ff].son[1]==f){rotate(f,0);rotate(x,0);}
            }
        }
        if(rt==0)root=x;
    }
    void ins(int d)
    {
        if(root==0)
        {
            add(d,0);root=len;
            return ;
        }
        int x=findip(d);
        if(d==a[x].d)
        {
            a[x].n++;
            update(x);
            splay(x,0);
        }
        else
        {
            add(d,x);
            update(x);
            splay(len,0);
        }
    }
    void del(int d)
    {
        int x=findip(d);splay(x,0);
        if(d!=a[x].d)return ;
        
        if(a[x].n>1){a[x].n--;update(x);return ;}
        if(a[x].son[0]==0 && a[x].son[1]==0){root=0;len=0;}
        else if(a[x].son[0]!=0 && a[x].son[1]==0){root=a[x].son[0];a[root].f=0;}
        else if(a[x].son[1]!=0 && a[x].son[0]==0){root=a[x].son[1];a[root].f=0;}
        else
        {
            int p=a[x].son[0];
            while(a[p].son[1]!=0)p=a[p].son[1];
            splay(p,x);
            
            int r,R;
            r=a[x].son[1];R=p;
            a[R].son[1]=r;
            a[r].f=R;
            
            root=R;a[root].f=0;
            update(R);
        }
    }
    int findqianqu(int d)
    {
        int x=findip(d);splay(x,0);
        if(d<a[x].d && a[x].son[0]!=0)
        {
            x=a[x].son[0];
            while(a[x].son[1]!=0)x=a[x].son[1];
        }
        if(d<a[x].d)x=0;
        return x;
    }
    int findhouji(int d)
    {
        int x=findip(d);splay(x,0);
        if(d>a[x].d && a[x].son[1]!=0)
        {
            x=a[x].son[1];
            while(a[x].son[0]!=0)x=a[x].son[0];
        }
        if(d>a[x].d)x=0;
        return x;
    }
    int findpaiming(int d)
    {
        int x=findip(d);
        splay(x,0);
        return a[a[x].son[0]].c+1;
    }
    int findshuzi(int k)
    {
        int x=root;
        while(1)
        {
            int lc=a[x].son[0],rc=a[x].son[1];
            if(k<=a[lc].c)x=lc;
            else if(k>a[lc].c+a[x].n){k-=a[lc].c+a[x].n;x=rc;}
            else break;
        }
        return a[x].d;
    }
    int n;
    int main()
    {
        scanf("%d",&n);len=0;root=0;
        int ans=0;int d;
        scanf("%d",&d);ans+=d;ins(d);
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&d);
            int ss=999999999;
            int lc=findqianqu(d),rc=findhouji(d);
            if(lc!=0) ss=abs(a[lc].d-d);
            if(rc!=0) ss=min(abs(a[rc].d-d),ss);
            ans+=ss;
            ins(d);
        }
        printf("%d
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    站点目录中的文件夹被删除后,应用程序池被重启
    silverlight中UserControl的属性在xaml文件中敲不出来的问题
    提取自Discuz NT 的验证码生成
    Asp.net首页生成静态页的一个比较好的方法
    asp.net 字符串格式化
    阻止用户关闭网页,提示保存的解决方案IE/FF/OP通用(未经测试)
    .NET程序如何防止被注入(整站)
    好久没有进步了
    C#数组排序
    我的静态页面
  • 原文地址:https://www.cnblogs.com/Never-mind/p/7630595.html
Copyright © 2011-2022 走看看