zoukankan      html  css  js  c++  java
  • POJ 2182 / HDU 2711 Lost Cows(平衡树)

    Description

    N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood 'watering hole' and drank a few too many beers before dinner. When it was time to line up for their evening meal, they did not line up in the required ascending numerical order of their brands. 
    Regrettably, FJ does not have a way to sort them. Furthermore, he's not very good at observing problems. Instead of writing down each cow's brand, he determined a rather silly statistic: For each cow in line, he knows the number of cows that precede that cow in line that do, in fact, have smaller brands than that cow. 
    Given this data, tell FJ the exact ordering of the cows. 

    Input

    * Line 1: A single integer, N 
    * Lines 2..N: These N-1 lines describe the number of cows that precede a given cow in line and have brands smaller than that cow. Of course, no cows precede the first cow in line, so she is not listed. Line 2 of the input describes the number of preceding cows whose brands are smaller than the cow in slot #2; line 3 describes the number of preceding cows whose brands are smaller than the cow in slot #3; and so on. 

    Output

    * Lines 1..N: Each of the N lines of output tells the brand of a cow in line. Line #1 of the output tells the brand of the first cow in line; line 2 tells the brand of the second cow; and so on.

    题目大意:有n只牛,每只牛有一个1~n的编号,每只牛知道前面有多少只牛编号比它小,问每只牛的编号是啥。

    思路:这题思路很多,这里采取平衡树的做法(O(n²)也是能AC的o(╯□╰)o)。先把1~n插入平衡树,从后往前扫,如果牛 i 前面有 pre[i] 只牛编号比它小,那么他就是还未被删掉的编号的第 pre[i] + 1个,然后删掉这个编号。

    代码(POJ 141MS):

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int MAXN = 8010;
     8 
     9 int key[MAXN], weight[MAXN], child[MAXN][2], size[MAXN];
    10 int stk[MAXN], top, cnt;
    11 
    12 inline int new_node(int k) {
    13     int x = (top ? stk[top--] : ++cnt);
    14     key[x] = k;
    15     size[x] = 1;
    16     weight[x] = rand();
    17     child[x][0] = child[x][1] = 0;
    18     return x;
    19 }
    20 
    21 inline void update(int &x) {
    22     size[x] = size[child[x][0]] + size[child[x][1]] + 1;
    23 }
    24 
    25 inline void rotate(int &x, int t) {
    26     int y = child[x][t];
    27     child[x][t] = child[y][t ^ 1];
    28     child[y][t ^ 1] = x;
    29     update(x); update(y);
    30     x = y;
    31 }
    32 
    33 void insert(int &x, int k) {
    34     if(x == 0) x = new_node(k);
    35     else {
    36         int t = (key[x] < k);
    37         insert(child[x][t], k);
    38         if(weight[child[x][t]] < weight[x]) rotate(x, t);
    39     }
    40     update(x);
    41 }
    42 
    43 void remove(int &x, int k) {
    44     if(key[x] == k) {
    45         if(child[x][0] && child[x][1]) {
    46             int t = weight[child[x][0]] < weight[child[x][1]];
    47             rotate(x, t); remove(child[x][t ^ 1], k);
    48         }
    49         else {
    50             stk[++top] = x;
    51             x = child[x][0] + child[x][1];
    52         }
    53     }
    54     else remove(child[x][key[x] < k], k);
    55     if(x > 0) update(x);
    56 }
    57 
    58 int kth(int &x, int k) {
    59     if(x == 0 || k <= 0 || k > size[x]) return 0;
    60     int s = 0;
    61     if(child[x][0]) s = size[child[x][0]];
    62     if(k == s + 1) return key[x];
    63     if(k <= s) return kth(child[x][0], k);
    64     return kth(child[x][1], k - s - 1);
    65 }
    66 
    67 int ans[MAXN], pre[MAXN];
    68 
    69 int main() {
    70     int n;
    71     scanf("%d", &n);
    72     pre[1] = 0;
    73     for(int i = 2; i <= n; ++i) scanf("%d", &pre[i]);
    74     int root = new_node(1);
    75     for(int i = 2; i <= n; ++i) insert(root, i);
    76     for(int i = n; i > 0; --i) {
    77         int t = kth(root, pre[i] + 1);
    78         ans[i] = t;
    79         remove(root, t);
    80     }
    81     for(int i = 1; i <= n; ++i)
    82         printf("%d
    ", ans[i]);
    83 }
    View Code

    使用pb_ds库。使用方法可以参考WC2015的论文《C++的pb_ds库在OI中的应用》。

    注意:这题在HDU上是多组数据,但是题目没有写清楚。

    代码(31MS):

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <ext/pb_ds/assoc_container.hpp>
     6 #include <ext/pb_ds/tree_policy.hpp>
     7 
     8 const int MAXN = 8010;
     9 
    10 __gnu_pbds::tree<int, __gnu_pbds::null_type, std::less<int>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update> tree;
    11 int ans[MAXN], pre[MAXN];
    12 int n;
    13 
    14 int main() {
    15     while(scanf("%d", &n) != EOF) {
    16         for(int i = 2; i <= n; ++i) scanf("%d", &pre[i]);
    17         tree.clear();
    18         for(int i = 1; i <= n; ++i)
    19             tree.insert(i);
    20         for(int i = n; i > 0; --i) {
    21             int t = *tree.find_by_order(pre[i]);
    22             ans[i] = t;
    23             tree.erase(t);
    24         }
    25         for(int i = 1; i <= n; ++i)
    26             printf("%d
    ", ans[i]);
    27     }
    28 }
    View Code
  • 相关阅读:
    【H3 BPM工作流程管理产品小故事】第六篇 条件可见与条件必填
    【H3 BPM工作流程管理产品小故事】第五篇 必填与水印文本
    【H3 BPM工作流程管理产品小故事】第四篇 子表创建
    【工作流程管理产品小故事】第三篇 参与者与数据加载
    【H3 BPM工作流程管理产品小故事】第二篇 文本默认值
    【H3 BPM工作流程管理产品小故事】第一篇 配置简单流程
    流程管理产品小故事汇总贴
    【H3 BPM工作流程产品小故事】第十四篇 数据字典与数据联动
    【H3 BPM工作流程产品小故事】第十三篇 消息通知
    【H3 BPM工作流程产品小故事】第十二篇 触发其他流程
  • 原文地址:https://www.cnblogs.com/oyking/p/3297529.html
Copyright © 2011-2022 走看看