Topic Links: http://poj.org/problem?id=2104
Topic Analysis: the problem given a period of value, and then given a section of the query interval [QL, QR], you need to give the query interval value in the order of the first k value;
This problem can be solved by using partition tree, the complexity of partitioning tree is O (Nlogn), and the complexity of querying the K-value of an interval is O (logn);
The code is as follows:
#include <cstdio>#include<iostream>#include<algorithm>using namespacestd;Const intMax_n =100000+Ten;intSorted[max_n];intto_left[ -][max_n];inttree[ -][max_n];voidBuild (intLintRintDeep ) { if(L = = r)return; intMid = (L + r) >>1; intLc_same = Mid-l +1; intL_pos = L, R_pos = mid +1; for(inti = l; I <= R; ++i) {if(Tree[deep][i] <Sorted[mid]) lc_same--; } for(inti = l; I <= R; ++i) {if(Tree[deep][i] <Sorted[mid]) tree[deep+1][l_pos++] =Tree[deep][i]; Else if(Tree[deep][i] = = Sorted[mid] && lc_same >0) {Lc_same--; Tree[deep+1][l_pos++] =Tree[deep][i]; } ElseTree[deep+1][r_pos++] =Tree[deep][i]; To_left[deep][i]= To_left[deep][l-1] + L_pos-l; } Build (L, Mid, deep+1); Build (Mid+1, R, Deep +1);}intQuery (intLintRintQlintQrintDeepintk) { if(L = =R)returnTree[deep][l]; intMid = (L + r) >>1; intCNT = TO_LEFT[DEEP][QR]-TO_LEFT[DEEP][QL-1]; if(CNT >=k) {intNEW_QL = L + to_left[deep][ql-1]-To_left[deep][l-1]; intNEW_QR = new_ql + CNT-1; returnQuery (L, Mid, new_ql, NEW_QR, deep +1, K); } Else { intNEW_QR = QR + to_left[deep][r]-TO_LEFT[DEEP][QR]; intNEW_QL = NEW_QR-(QR-QL-CNT); returnQuery (Mid +1, R, New_ql, NEW_QR, deep +1KCNT); }}intMain () {intN, Query_times; scanf ("%d%d", &n, &query_times); for(inti =1; I <= N; ++i) {scanf ("%d", &tree[0][i]); Sorted[i]= tree[0][i]; } sort (sorted+1, sorted + n +1); Build (1N0); for(inti =0; i < query_times; ++i) {intQL, QR, K, ans; scanf (" %d%d%d", &QL, &QR, &k); Ans= Query (1, N, QL, QR,0, K); printf ("%d\n", ans); } return 0;}
POJ 2104 k-th Number (partition tree)