Splay树-Codevs 1296 营业额统计
Codevs 1296 营业额统计
题目描述 Description
Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 
该天的最小波动值 = min|该天以前某一天的营业额−该天营业额| 
当最小波动值越大时,就说明营业情况越不稳定。 
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 
第一天的最小波动值为第一天的营业额。
输入描述 Input Description
第一行为正整数n(n<=32767),表示该公司从成立一直到现在的天数,接下来的n行每行有一个正整数ai(ai<=1000000),表示第i天公司的营业额。
输出描述 Output Description
输出文件仅有一个正整数,即每天最小波动值之和,小于231
样例输入 Sample Input
6
5
1
2
5
4
6
样例输出 Sample Output
12
数据范围及提示 Data Size & Hint
结果说明:5+|1−5|+|2−1|+|5−5|+|4−5|+|6−5|=5+4+1+0+1+1=12
题解
很显然,这道题是一道衤果的Splay树。
手写Splay:
#include <iostream>
#define maxn 50005
#define INF 1E8
using namespace std;
int min(int a, int b)
{
    return a < b ? a : b;
}
int abs(int x)
{
    return x < 0 ? (-x) : x;
}
struct splay_tree
{
    int ch[maxn][2], val[maxn], root, fa[maxn], n;
    inline int wson(int x)
    {
        if(x == ch[fa[x]][0])
            return 0;
        return 1;
    }
    inline void rotate(int x)
    {
        int y = fa[x], z = fa[y], a = wson(x), b = wson(y);
        ch[z][b] = x; fa[x] = z;
        ch[y][a] = ch[x][!a]; fa[ch[x][!a]] = y;
        ch[x][!a] = y; fa[y] = x;
    }
    inline void splay(int x, int p = 0)
    {
        while(fa[x] != p)
        {
            int y = fa[x], z = fa[y];
            if(z == p)
                rotate(x);
            else
            {
                if(wson(x) == wson(y))
                {
                    rotate(y);
                    rotate(x);
                }
                else
                {
                    rotate(x);
                    rotate(x);
                }
            }
        }
        if(!p) root = x;
    }
    inline void insert(int a)
    {
        if(!n)
        {
            n = 1;
            root = 1;
            val[1] = a;
            ch[1][0] = ch[1][1] = fa[1] = 0;
            return;
        }
        int x = root, y;
        while(x)
        {
            y = x;
            if(a < val[x])
                x = ch[x][0];
            else x = ch[x][1];
        }
        ++n;
        if(a < val[y])
        {
            ch[y][0] = n;
            val[n] = a;
            fa[n] = y;
            ch[n][0] = ch[n][1] = 0;
            splay(n, 0);
        }
        else
        {
            ch[y][1] = n;
            val[n] = a;
            fa[n] = y;
            ch[n][0] = ch[n][1] = 0;
            splay(n, 0);
        }
    }
    inline int at(int loc)
    {
        return val[loc];
    }
    inline int last(int loc)
    {
        int x = loc, y;
        if(ch[x][0])
        {
            x = ch[x][0];
            while(x)
            {
                y = x;
                x = ch[x][1];
            }
            splay(y);
            return y;
        }
        y = fa[x];
        while(y && x == ch[y][0])
        {
            x = y;
            y = fa[y];
        }
        splay(y);
        return y;
    }
    inline int next(int loc)
    {
        int x = loc, y;
        if(ch[x][1])
        {
            x = ch[x][1];
            while(x)
            {
                y = x;
                x = ch[x][0];
            }
            splay(y);
            return y;
        }
        y = fa[x];
        while(y && x == ch[y][1])
        {
            x = y;
            y = fa[y];
        }
        splay(y);
        return y;
    }
    inline int find_lower_bound(int key)
    {
        int x = root, y;
        while(x)
        {
            y = x;
            if(key == val[x])
                return x;
            else
            {
                if(key < val[x])
                    x = ch[x][0];
                else x = ch[x][1];
            }
        }
        if(val[y] < key)
            return next(y);
        splay(y);
        return y;
    }
};
splay_tree tree;
int main()
{
    int n;
    tree.insert(INF);
    tree.insert(-INF);
    cin >> n;
    int ans, a, pos, de;
    cin >> a;
    ans = a;
    tree.insert(a);
    for(int i = 1; i < n; ++i)
    {
        cin >> a;
        pos = tree.find_lower_bound(a);
        de = min(abs(a - tree.at(pos)), abs(tree.at(tree.last(pos)) - a));
        ans += de;
        tree.insert(a);
    }
    cout << ans;
    return 0;
}
STL模板(STL)大法好!
代码:
据说智商达到180的人才会看到哦~,语文老师告诉我这叫留给读者想象的空间~
Splay树-Codevs 1296 营业额统计的更多相关文章
- CJOJ 1308 【HNOI 2002 】营业额统计 / CodeVS 1296 营业额统计(STL,二分)
		
CJOJ 1308 [HNOI 2002 ]营业额统计 / CodeVS 1296 营业额统计(STL,二分) Description Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一 ...
 - CodeVS 1296 营业额统计
		
1296 营业额统计2002年 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description Tiger最近被公司升任为营业部经理, ...
 - codevs 1296 营业额统计 (splay 点操作)
		
题目大意 每次加入一个值,并且询问之前加入的数中与该数相差最小的值. 答案输出所有相差值的总和. 解题分析 = = 参考程序 #include <bits/stdc++.h> using ...
 - 【wikioi】1296 营业额统计
		
题目链接:http://www.wikioi.com/problem/1296/ 算法:Splay 这是非常经典的一道题目,用Splay树来维护营业额,每天的最小波动值就等于 min{树根-树根的前驱 ...
 - splay 1296 营业额统计
		
有一个点超时,确实是个很简单的splay#include<cstdio> #include<iostream> using namespace std; int n,shu[1 ...
 - Splay入门题目 [HNOI2002]营业额统计
		
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1588 这道题貌似很多中做法,我先是用multiset交了一发,然后又写了一发splay. ...
 - 日常[splay]:水题记——营业额统计
		
没错这就是让我深陷splay之中的罪魁祸首,昨天打了一下午结果发现是玄学错误的那个 人生第一棵splay平衡树 题目大意:求一段序列,小于当前元素的最大值和大于当前元素的最小值.从该元素前面的元素找. ...
 - treap 1296 营业额统计
		
有一个点答案错误,求大神指教 #include<cstdio>#include<iostream>#include<cstdlib>#include<ctim ...
 - AC日记——营业额统计 1296 codevs
		
1296 营业额统计 2002年 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 查看运行结果 题目描述 Description Tiger ...
 
随机推荐
- vsftpd 创建虚拟用户
			
1.添加一个宿主用户:useradd vsftpd -s /sbin/nologin2.安装db4-utils,通过本底数据文件实现虚拟用户访问yum install db4-utils3.创建ftp ...
 - Python学习笔记07
			
时间: tickets 时间元组 格式化的时间 日历 import time tickets = time.time() print tickets print time.localtime() ...
 - Angular JS中的依赖注入
			
依赖注入DI angularjs中与DI相关有angular.module().angular.injector(). $injector.$provide. DI 容器3要素:服务的注册.依赖关系的 ...
 - HDU 2222 & ac自动机模板
			
题意: 求n个模板串在匹配串中出现了几个. SOL: 反正就是模板啦...似乎比KMP都简单----这么说似乎有点不道德...毕竟先看的KMP而他们并没有什么不同... 貌似自己的理解和他们画的图还是 ...
 - 转:关于垂直网格与CSS基线对其的探讨
			
网页设计布局中一直比较流行网格对齐,但只是针对水平的对齐,很少或者没有涉及垂直对齐,这篇文章很详细的讲解了垂直网格,乃至基线对其的相关,而css3中的多列布局的也使其显得更为重要,因此还是很有必要去了 ...
 - 记忆用户设置-提升程序的体验VB/C#
			
有时候,设计的程序有很多的控件,甚至多达近百个,尤其是一些工控软件等,程序运行所需的各种参数都是由用户通过这些控件设置而来,那么记录用户的设置就显得十分必要.如果程序出现异常,起码重新打开可以不用再一 ...
 - 【HDU】1850 Being a Good Boy in Spring Festival
			
http://acm.hdu.edu.cn/showproblem.php?pid=1850 题意:同nim...顺便求方案数... #include <cstdio> #include ...
 - ssh免密登录
			
背景:搭建Hadoop环境需要设置无密码登陆,所谓无密码登陆其实是指通过证书认证的方式登陆,使用一种被称为"公私钥"认证的方式来进行ssh登录. 在linux系统中,ssh是远程登 ...
 - 在Linux中安装Tomcat
			
带Linux的虚拟机中安装Tomcat 一.从官方网站上下载tomcat软件包.http://tomcat.apache.org/ apache-tomcat-7.0.33.tar.gz 二.下载到本 ...
 - 将bootstrap弹出框的点击弹出改为鼠标移入弹出
			
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...