HDU 4417 Super Mario (Hangzhou offline line segment tree in 12 years | online line division tree)

Source: Internet
Author: User
Tags cmath

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 ;}

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.