zoukankan      html  css  js  c++  java
  • 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
    ", res);
    129     }
    130 }

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

  • 相关阅读:
    bzoj 1051: [HAOI2006]受欢迎的牛
    bzoj 1192: [HNOI2006]鬼谷子的钱袋
    一些动规水题
    USACO 2014 Open Silver Fairphoto
    USACO 2013 Nov Silver Pogo-Cow
    09day1
    09day2
    08day2
    08day1
    07day2
  • 原文地址:https://www.cnblogs.com/AC-Phoenix/p/4430143.html
Copyright © 2011-2022 走看看