码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-04-15 21:25:43      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:

//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

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

标签:

原文地址:http://www.cnblogs.com/AC-Phoenix/p/4430143.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!