1588: [HNOI2002]营业额统计 splay tree

//http://www.lydsy.com/JudgeOnline/problem.php?id=1588

//题意:每读入一个数,在前面输入的数中找到一个与该数相差最小的一个,把所有的差值绝对值加起来并输出

  1 #include "bits/stdc++.h"
  2 using namespace std;
  3 const int maxn = 100010;
  4 const int INF = 0x3f3f3f3f;
  5 struct SplayTreeNode
  6 {
  7     int key;
  8     int father, child[2];
  9 }splayTreeNode[maxn];
 10 int splayTreeRoot, cntSplayTreeNode;
 11
 12 int n, num;
 13
 14 void AddSonNode(int &son, int father, int key)
 15 {
 16     ++cntSplayTreeNode;
 17     son = cntSplayTreeNode;
 18     splayTreeNode[son].key = key;
 19     splayTreeNode[son].father = father;
 20     splayTreeNode[son].child[0] = splayTreeNode[son].child[1] = 0;
 21 }
 22
 23 void Rotate(int index, bool pos)
 24 {
 25     int indexFather = splayTreeNode[index].father;
 26     int indexFatherFather = splayTreeNode[indexFather].father;
 27     int indexSon = splayTreeNode[index].child[!pos];
 28     //父节点 子节点
 29     splayTreeNode[ indexFather ].child[pos] = indexSon;
 30     splayTreeNode[ indexSon ].father = indexFather;
 31     //父节点的父节点 原节点
 32     if(indexFatherFather) {
 33         bool posFather = splayTreeNode[ indexFatherFather ].child[1] == indexFather;
 34         splayTreeNode[ indexFatherFather ].child[posFather] = index;
 35     }
 36     splayTreeNode[index].father = splayTreeNode[indexFather].father;
 37     //原节点 父节点
 38     splayTreeNode[index].child[!pos] = indexFather;
 39     splayTreeNode[indexFather].father = index;
 40 }
 41
 42 void Splay(int index, int goalFather)
 43 {
 44     int indexFather;
 45     while((indexFather = splayTreeNode[index].father) != goalFather) {
 46         bool pos = splayTreeNode[indexFather].child[1] == index;
 47         //旋转一次能达到目的
 48         if(splayTreeNode[indexFather].father == goalFather) {
 49             Rotate(index, pos);
 50         }
 51         else {
 52             bool posFather = splayTreeNode[ splayTreeNode[indexFather].father ].child[1] == indexFather;
 53             if(pos != posFather) {
 54                 //方位不同,子节点旋转两次
 55                 Rotate(index, pos);
 56                 Rotate(index, posFather);
 57             }
 58             else {
 59                 //方位相同,先旋转父节点,再旋转子节点
 60                 Rotate(indexFather, pos);
 61                 Rotate(index, pos);
 62             }
 63         }
 64     }
 65     //旋转到备用节点 0 下方,则为根节点
 66     if(goalFather == 0)
 67         splayTreeRoot = index;
 68 }
 69
 70 //失败返回 0,成功返回 1
 71 bool InsertNode(int key)
 72 {
 73     int index = splayTreeRoot;
 74     while(splayTreeNode[index].child[ splayTreeNode[index].key < key ]) {
 75         //不重复插入
 76         if(splayTreeNode[index].key == key) {
 77             //旋转到根节点
 78             Splay(index, 0);
 79             return 0;
 80         }
 81         index = splayTreeNode[index].child[ splayTreeNode[index].key < key ];
 82     }
 83     AddSonNode(splayTreeNode[index].child[ splayTreeNode[index].key < key ], index, key);
 84     Splay(splayTreeNode[index].child[ splayTreeNode[index].key < key ], 0);
 85     return 1;
 86 }
 87
 88 int getColost_1(int index)
 89 {
 90     int indexSon = splayTreeNode[index].child[0];
 91     if(indexSon == 0)
 92         return INF;
 93     while(splayTreeNode[indexSon].child[1])
 94         indexSon = splayTreeNode[indexSon].child[1];
 95     return splayTreeNode[index].key - splayTreeNode[indexSon].key;
 96 }
 97
 98 int getColost_2(int index)
 99 {
100     int indexSon = splayTreeNode[index].child[1];
101     if(indexSon == 0)
102         return INF;
103     while(splayTreeNode[indexSon].child[0])
104         indexSon = splayTreeNode[indexSon].child[0];
105     return -splayTreeNode[index].key + splayTreeNode[indexSon].key;
106 }
107
108 int main()
109 {
110     int i;
111     while(scanf("%d", &n) != EOF) {
112         splayTreeRoot = cntSplayTreeNode = 0;
113         int res = 0;
114         for(i = 1; i <= n; ++i) {
115             if(scanf("%d", &num) == EOF)   //数据有些问题,要加上这个
116                 num = 0;
117             if(i == 1) {
118                 res += num;
119                 AddSonNode(splayTreeRoot, 0, num);
120                 continue;
121             }
122             if(InsertNode(num) == 0)
123                 continue;
124             int tmp_1 = getColost_1(splayTreeRoot);
125             int tmp_2 = getColost_2(splayTreeRoot);
126             res += min(tmp_1, tmp_2);
127         }
128         printf("%d\n", res);
129     }
130 }

//窝只是想给程序的加一点可读性...没想到写成了这个鬼样子QAQ

时间: 2024-10-08 07:29:10

1588: [HNOI2002]营业额统计 splay tree的相关文章

HNOI2002]营业额统计 Splay tree

保存模板: 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<string> 6 #include<string.h> 7 8 typedef long long ll; 9 using namespace std; 10 #define N 100005 11 #define inf 1<<

BZOJ 题目1588: [HNOI2002]营业额统计(Splay Tree 求前驱后继)

1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 10828  Solved: 3771 [Submit][Status][Discuss] Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者

BZOJ 1588: [HNOI2002]营业额统计 双向链表 / splay / treap

1588: [HNOI2002]营业额统计 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题.经济管理学上定义了一种最小波动值来衡量这

BZOJ 1588: [HNOI2002]营业额统计

1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 14396  Solved: 5521[Submit][Status][Discuss] Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者是其

BZOJ1588 营业额统计 splay tree

最基本的平衡树操作吧,第一次学splay的可以做一下 只需要插入,删除,旋转,求前驱,后继这5个操作吧 不喜欢用指针,用数组写的 <span style="color:#00cccc;">//HNOI2002营业额统计 #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define INF 1<<30 #define

bzoj 1588: [HNOI2002]营业额统计 treap

1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 13902  Solved: 5225[Submit][Status][Discuss] Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者是其

BZOJ1588 [HNOI2002]营业额统计 splay模板

1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 16189  Solved: 6482 [Submit][Status][Discuss] Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者

bzoj-1588 1588: [HNOI2002]营业额统计(BST)

题目链接: 1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 13596  Solved: 5049[Submit][Status][Discuss] Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大

BZOJ 1588([HNOI2002]营业额统计-set)

1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 10371  Solved: 3597 [Submit][Status][Discuss] Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者