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