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;
    }
  • 相关阅读:
    “约瑟夫问题”实现代码
    “百钱买百鸡”问题
    链栈的表示与实现
    个人作品Demo3PLY文件的读取
    系统程序员成长计划容器与算法(一)(下)
    循环单链表的建立
    链式队列元素删除实现
    使用链栈实现数制的转换
    系统程序员成长计划容器与算法(二)(上)
    个人作品Demo4STL文件读取
  • 原文地址:https://www.cnblogs.com/Zars19/p/6657198.html
Copyright © 2011-2022 走看看