Reprinted please indicate the source, thank youHttp://blog.csdn.net/acm_cxlove/article/details/7854526
By --- cxlove
Question: give some numbers and query the number of numbers smaller than h in the interval
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4417
This is a simple question during the competition.
Cry ~~~ It took half a day for TLE to adjust its posture using an offline line segment tree.
After reading all the inquiry offline, sort by H from small to large. Then all nodes are sorted in ascending order. Then, according to the queried H, the vertex smaller than H is added to the line segment tree, and then a range and.
# Include <iostream> # include <cstdio> # include <map> # include <cstring> # include <cmath> # include <vector> # include <algorithm> # include <set> # include <string> # include <queue> # define INF 1 <28 # define M 6000005 # define n 100005 # define maxn 300005 # define min (, b) (a) <(B )? (A) :( B) # define max (A, B) (a)> (B )? (A) :( B) # define Pb (a) push_back (a) # define MEM (a, B) memset (a, B, sizeof ()) # define ll long # define mod 1000000007 # define lson step <1 # define rson step <1 | 1 using namespace STD; struct tree {int left, right, CNT ;} L [N * 4]; struct q {int L, R, H, ID; bool operator <(const Q Q1) const {return H <q1.h ;}} que [N]; struct node {int POs, Val; bool operator <(const node N1) const {return Val <n1.val ;}} nod [N]; void bulid (INT step, int L, int R) {L [STEP]. left = L; L [STEP]. right = r; L [STEP]. CNT = 0; If (L = r) return; int M = (L + r)/2; bulid (lson, l, m); bulid (rson, m + 1, R);} void Update (INT step, int POS) {L [STEP]. CNT ++; If (L [STEP]. left = L [STEP]. right) return; int M = (L [STEP]. left + L [STEP]. right)/2; If (Pos <= m) Update (lson, POS); else Update (rson, POS);} int query (INT step, int L, int R) {If (L [STEP]. left = L & L [STEP]. right = r) return l [STEP]. CNT; int M = (L [STEP]. left + L [STEP]. right)/2; // printf ("% d \ n", l [STEP]. left, L [STEP]. right, l, R); If (r <= m) return query (lson, L, R); else if (L> m) return query (rson, l, r); else return query (lson, l, m) + query (rson, m + 1, R);} int ans [N]; int main () {int t, CAS = 0, N, Q; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & Q); For (INT I = 0; I <n; I ++) {scanf ("% d", & nod [I]. val); nod [I]. pos = I + 1 ;}for (INT I = 0; I <q; I ++) {que [I]. id = I; scanf ("% d", & que [I]. l, & que [I]. r, & que [I]. h);} Sort (nod, nod + n); sort (que, que + q); bulid (1, 1, n); printf ("case % d: \ n ", ++ CAS); int K = 0; For (INT I = 0; I <q; I ++) {While (k <n & nod [K]. val <= que [I]. h) {update (1, nod [K]. pos); k ++;} ans [que [I]. id] = query (1, que [I]. L + 1, que [I]. R + 1) ;}for (INT I = 0; I <q; I ++) printf ("% d \ n", ANS [I]);} return 0 ;}
In fact, we can also divide the tree, ah
The second answer is used to determine the relationship between the k-th large number of the interval and H.
The former is a little faster
# Include <iostream> # include <cstdio> # include <map> # include <cstring> # include <cmath> # include <vector> # include <algorithm> # include <set> # include <string> # include <queue> # define INF 1 <28 # define M 6000005 # define n 100005 # define maxn 300005 # define min (, b) (a) <(B )? (A) :( B) # define max (A, B) (a)> (B )? (A) :( B) # define Pb (a) push_back (a) # define MEM (a, B) memset (a, B, sizeof ()) # define ll long # define mod 1000000007 # define lson step <1 # define rson step <1 | 1 using namespace STD; struct node {int left, right; int sum;} l [N * 4]; int SA [N], num [20] [N], CNT [20] [N]; // SA is sorted. Num records the sorting result of each layer. CNT [Deep] [I] indicates the deep layer, how many of the preceding I numbers enter the left subtree void bulid (INT step, int L, int R, int deep) {L [STEP]. left = L; L [STEP]. right = r; If (L = r) return; int mid = (L + r)> 1; int mid_val = sa [Mid], lsum = mid-L + 1; For (INT I = L; I <= r; I ++) if (Num [Deep] [I] <mid_val) lsum --; // lsum indicates how many values int L = L, r = Mid + 1 are required in the left subtree; For (INT I = L; I <= r; I ++) {if (I = L) CNT [Deep] [I] = 0; else CNT [Deep] [I] = CNT [Deep] [I-1]; if (Num [Deep] [I] <mid_val | (Num [Deep] [I] = mid_val & lsum> 0 )) {// left subtree num [Deep + 1] [L ++] = num [Deep] [I]; CNT [Deep] [I] ++; if (Num [Deep] [I] = mid_val) lsum --;} else num [Deep + 1] [R ++] = num [Deep] [I];} bulid (2 * step, L, mid, deep + 1); bulid (2 * Step + 1, Mid + 1, R, deep + 1 );} int query (INT step, int L, int R, int K, int deep) {If (L = r) return num [Deep] [l]; int S1, S2; // S1 is [L [STEP]. number of left subtree in left L-1] If (L [STEP]. left = L) S1 = 0; else S1 = CNT [Deep] L-1]; S2 = CNT [Deep] [r]-S1; // S2 is [L, r] Number of left subtree int M = (L [STEP]. left + L [STEP]. right)/2; If (k <= S2) // The number of left subtree is greater than K. Recursive left subtree return query (lson, L [STEP]. left + S1, L [STEP]. left + S1 + s2-1, K, deep + 1); int b1 = l-1-L [STEP]. left + 1-s1; // B1 is [L [STEP]. number of right subtree in left L-1]: int b2 = r-L + 1-s2; // B2 is [L, r] right subtree number return query (rson, m + 1 + B1, m + 1 + B1 + b2-1, k-s2, deep + 1 );} int slove (int l, int R, int h) {int ans = 0, low = 1, high = r-L + 1, mid; while (low <= high) {mid = (low + high)/2; int TMP = query (1, L, R, mid, 0); If (TMP <= h) {ans = mid; low = Mid + 1;} else high = mid-1;} return ans;} int main () {int N, Q, T, CAS = 0; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & Q); For (INT I = 1; I <= N; I ++) {scanf ("% d", & SA [I]); num [0] [I] = sa [I];} sort (SA + 1, Sa + 1 + n); bulid (1, 1, n, 0); printf ("case % d: \ n", ++ CAS ); while (Q --) {int L, R, H; scanf ("% d", & L, & R, & H); L ++; r ++; printf ("% d \ n", slove (L, R, H) ;}} return 0 ;}