POJ 2104 basic topic for Tree Learning

Source: Internet
Author: User

Question: n numbers are given, and m queries are made. The k-th digit in the [a, B] of each query interval is output. A Data Structure is used to divide the tree. Tree Division means that each node stores all the elements in the [l, r] interval. The order of elements is the same as that of the original array, however, the elements of the two subtree are the first (r-l + 1)/Two (r-l + 1) After all the elements of the node are sorted to the left subtree, and the remaining to the right subtree, at the same time, a sum field is maintained. sum [I] indicates how many of the vertices l -- I have entered the left subtree. For query, In the range [l, r], find the k-th large number, t is the node, and tree [t]. l, tree [t]. r indicates the left and right intervals of the node. Mid is the range value. 1. sum [r]-sum [L-1]> = k, search for LL (t), and the interval corresponds to [tree [t]. l + sum [L-1], tree [t]. l + sum [r]-1] 2. sum [r]-sum L-1] <k, search for RR (t ), the interval corresponds to [mid + 1 + l-tree [t]. l-sum [L-1], mid + 1 + r-tree [t]. l-sum [r] For details, see the code [cpp] # include <iostream> # include <cstdio> # include <algorithm> # include <string> # include <cmath> # include <cstring> # include <queue> # include <set> # include <vector> # include <stack> # include <map> # include <iomanip> # define P I acos (-1.0) # define Max 100005 # define inf 1 <28 # define LL (x) (x <1) # define RR (x) (x <1 | 1) # define FOR (I, s, t) for (int I = (s); I <= (t); ++ I) # define ll long # define mem (a, B) memset (a, B, sizeof (a) # define mp (a, B) make_pair (a, B) using namespace std; int lessmid [20] [Max]; // number of values smaller than the mid value in the interval. Int seg [20] [Max]; int num [Max]; struct seg_tree {int l, r;} tree [Max * 4]; void build_tree (int l, int r, int u, int d) {tree [u]. l = l, tree [u]. r = r; if (l = r) return; int mid = l + r> 1; int issame = mid-l + 1; // The total number of elements on the left side of the for (int I = l; I <= r; I ++) if (seg [d] [I] <num [mid]) // if all the values smaller than the center value are placed on the issame --; // issame -- on the left, this value can be placed on the left, and the total number on the left is reduced. // The total number of issame is the number of digits that are equal to or equal to the value. Int lpos = l, rpos = mid + 1; for (int I = l; I <= r; I ++) {if (I = l) lessmid [d] [I] = 0; // The number of lessmid [d] [I] records less than or equal to the number of values in layer d and between [l, I. Else lessmid [d] [I] = lessmid [d] [I-1]; if (seg [d] [I] <num [mid]) {lessmid [d] [I] ++; // less than the median value. The count is added with seg [d + 1] [lpos ++] = seg [d] [I]; // put this number to the left} else if (seg [d] [I]> num [mid]) {seg [d + 1] [rpos ++] = seg [d] [I]; // similarly} else // if they are equal, the issame element above is required. {if (issame> 0) // if issame> 0, the left side is not filled, and the number equal to the value can be left. {Issame --; lessmid [d] [I] ++; // here, the number is equal to the number of values. Seg [d + 1] [lpos ++] = seg [d] [I];} else seg [d + 1] [rpos ++] = seg [d] [I] ;}} build_tree (l, mid, LL (u), d + 1 ); build_tree (mid + 1, r, RR (u), d + 1);} int update (int l, int r, int u, int d, int cnt) {if (l = r) return seg [d] [l]; int num1, num2; if (l = tree [u]. l) {num1 = lessmid [d] [r]; num2 = 0;} else {num1 = lessmid [d] [r]-lessmid [d L-1]; // put the number of values smaller than or equal to the value of [l, r] on the left num2 = lessmid [d] L-1]; // [tree [u]. l L-1] is less than or equal to the number of values, placed in Left} if (num1> = cnt) {return update (tree [u]. l + num2, tree [u]. l + num1 + num2-1, LL (u), d + 1, cnt);} else {int mid = tree [u]. l + tree [u]. r> 1; int num4 = l-tree [u]. l-num2; // [tree [u]. l, l-1] The total number to the right. Int num3 = r-l + 1-num1; // the total number of places [l, r] on the right. Return update (mid + num4 + 1, mid + num3 + num4, RR (u), d + 1, cnt-num1) ;}} int main () {int n, m; cin> n> m; for (int I = 1; I <= n; I ++) {scanf ("% d ", & num [I]); seg [1] [I] = num [I];} sort (num + 1, num + n + 1); build_tree (1, n, 1, 1); while (m --) {int a, B, c; scanf ("% d", & a, & B, & c ); printf ("% d \ n", update (a, B, 1, 1, c);} return 0 ;}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.