POJ Lost Cows

【题解】

       参考https://blog.csdn.net/acmer_hades/article/details/46272605。设置数组pre_smaller,其中第i个元素即为输入的第i项,则显然pre_smaller[1] = 0。build_tree建立树结构,分解区间[1, N],其中每个节的度要么为2,要么为0。query中参数smaller_num表示自身以及队列前方比自己编号小的cows的总数。确实是非常简洁的方法,将线段数组运用得淋漓尽致!不愧是NOI大神

【代码】

 1 #include <iostream>
 2 #include <cstdlib>
 3 using namespace std;
 4 
 5 #define maxn 100001
 6 
 7 int N;
 8 int pre_smaller[maxn], ans[maxn];
 9 
10 struct node 
11 {
12     int left_val, right_val, len;
13 }s[4*maxn];
14 
15 void build_tree(int root, int left_val, int right_val)
16 {
17     s[root].left_val = left_val;
18     s[root].right_val = right_val;
19     s[root].len = right_val - left_val + 1;
20     if (left_val == right_val)return;
21     build_tree(2 * root, left_val, (left_val + right_val) / 2);
22     build_tree(2 * root + 1, 1 + (left_val + right_val) / 2, right_val);
23 }
24 
25 int query(int root, int smaller_num)
26 {
27     s[root].len--;
28     if (s[root].left_val == s[root].right_val)return s[root].left_val;
29     else if (s[2 * root].len >= smaller_num)return query(2 * root, smaller_num);
30     else return query(2 * root + 1, smaller_num - s[2 * root].len);
31 }
32 
33 int main()
34 {
35     cin >> N;
36     for (int i = 2; i <= N; i++)cin >> pre_smaller[i];
37     pre_smaller[1] = 0;
38     build_tree(1, 1, N);
39     for (int i = N; i >= 1; i--)ans[i] = query(1, pre_smaller[i] + 1);
40     for (int i = 1; i <= N; i++)printf("%d
", ans[i]);
41     return 0;
42 }
原文地址:https://www.cnblogs.com/Jeffrey-Y/p/9824307.html