zoukankan      html  css  js  c++  java
  • [BZOJ 1588][HNOI2002]营业额统计(Splay)

    Description

    Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。

    Solution

    用Splay维护,每插入一个值,如果w==1就找前驱和后继来确定最小波动值

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #define lc(x) t[x].ch[0]
    #define rc(x) t[x].ch[1]
    #define Min(a,b) (a<b?a:b)
    #define Abs(x) (x>=0?x:-x)
    #define INF 0x3f3f3f3f;
    using namespace std;
    int n,root,siz=0,sum=0;
    struct Node{
        int ch[2],father,val,w,siz;
        Node(){ch[0]=ch[1]=father=val=w=siz=0;}
    }t[40000];
    int Read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=x*10+c-'0';c=getchar();
        }
        return x*f;
    }
    void Update(int x)
    {
        t[x].siz=t[lc(x)].siz+t[rc(x)].siz+t[x].w;
    }
    void Rotate(int x,int &k)
    {
        int y=t[x].father;
        int z=t[y].father;
        int p=(t[y].ch[0]==x)?0:1;
        if(y==k)k=x;
        else
        {
            if(t[z].ch[0]==y)t[z].ch[0]=x;
            else t[z].ch[1]=x;
        }
        t[x].father=z;
        t[y].ch[p]=t[x].ch[p^1];
        t[t[x].ch[p^1]].father=y;
        t[x].ch[p^1]=y;
        t[y].father=x;
        Update(y),Update(x);
    }
    void Splay(int x,int &k)
    {
        while(k!=x)
        {
            int y=t[x].father;
            int z=t[y].father;
            if(y!=k)
            {
                if((t[y].ch[0]==x)^(t[z].ch[0]==y))
                Rotate(x,k);
                else Rotate(y,k);
            }
            Rotate(x,k);
        }
    }
    void Insert(int &x,int k,int f)
    {
        if(!x)
        {
            ++siz;x=siz;
            t[x].father=f;
            t[x].w=t[x].siz=1;
            t[x].val=k;
            Splay(x,root);
            return;
        }
        t[x].siz++;
        if(k<t[x].val)Insert(t[x].ch[0],k,x);
        else if(k>t[x].val) Insert(t[x].ch[1],k,x);
        else t[x].w++,Splay(x,root);
    }
    int Pre()
    {
        int p=t[root].ch[0];
        if(!p)return INF;
        while(t[p].ch[1])
        p=t[p].ch[1];
        return t[p].val;
    }
    int Suc()
    {
        int p=t[root].ch[1];
        if(!p)return INF;
        while(t[p].ch[0])
        p=t[p].ch[0];
        return t[p].val; 
    }
    int main()
    {
        n=Read();
        for(int i=1;i<=n;i++)
        {
            int x=Read();
            Insert(root,x,0);
            if(i==1)
            {
                sum+=x;
                continue;
            }
            if(t[root].w==1)
            {
                int a=x-Pre(),b=x-Suc();
                a=Abs(a),b=Abs(b);
                sum+=Min(a,b);
            }
        }
        printf("%d
    ",sum);
        return 0;
    }
  • 相关阅读:
    C#中 @ 的用法
    ASP.NET页面间传值
    ASP.NET中常用的文件上传下载方法
    把图片转换为字符
    把图片转换为字符
    JavaScript 时间延迟
    Using WSDLs in UCM 11g like you did in 10g
    The Definitive Guide to Stellent Content Server Development
    解决RedHat AS5 RPM安装包依赖问题
    在64位Windows 7上安装Oracle UCM 10gR3
  • 原文地址:https://www.cnblogs.com/Zars19/p/6657198.html
Copyright © 2011-2022 走看看