Смысл проблем
Номер, присвоенный $ N $, $ Q $ Тогда есть время, чтобы спросить, спросить каждого из $ L, R, P, K $ исключительно для одного или ответа, является реальным значением (то есть, с помощью силы). Каждый запрос, выход $ [L, R] $ малых $ K $ $ | ра [я] | $.
анализ
Председатель дерева обычно используется, чтобы найти большие участки K, на самом деле, его практический эффект заключается в подсчете количества значений в пределах определенного диапазона. Таким образом,
Для каждого запроса, половина из ответов на возможные ответы $ X $, до $ R_l \ сим R_r $ дерево линии, чтобы найти $ [точек, р + х] $ ли $ к $.
Председатель дерево строится на ценностях , эта проблема данных в диапазоне от $ 10 ^ 6 $, не дискретные ( слова силой дискретного я не буду )
Почувствовав некоторые карты часто, 32 раз, 55 раз пространства TLE, изменилось в 64 раза более (почему ах)
# include <бит / STDC ++ Х.> что используя пространство имен STD; Const INT MAXN 1E5 + = 100 ; INT н-, м; // Int А [MAXN]; // INT RT [MAXN], LC [. << MAXN 5], гс [MAXN << 5], SUM [MAXN << 5]; // RT: разные версии корневого узла ОГО / гса: сын левой и правый сын (общественная) сумма: и (общественный) Int RT [MAXN], LC [MAXN * 64 ], RC [MAXN * 64 ], СУММА [MAXN * 64 ]; INT node_cnt; // Узел общее количество, pnt_disc: цифровое значение , соответствующее Б Int диапазоне = 1000000 ; // диапазон данных, сегмент дерево размер пустот Строить ( ИНТ& Last_node, INT л, INT г) { last_node = ++ node_cnt; сумма [last_node] = 0 ; если (л == г) возвращение ; Int середине = (L + R) >> 1 ; построить (ЖХ [last_node], L, середина); построить (RC [last_node], середина + 1 , г); } Int изменить ( INT pre_rt, INT v, INT л, INT г) { INT new_rt = ++ node_cnt; ЖХ [new_rt] =ЖХ [pre_rt]; RC [new_rt] = гс [pre_rt]; сумма [new_rt] = сумма [pre_rt] + 1 ; Int середине = (L + R) >> 1 ; если (л == г) возвращение new_rt; если (середина> = V) LC [new_rt] = изменение (ЖХ [new_rt], V, L, середина); остальное гс [new_rt] = модифицируют (RC [new_rt], V, середина + 1 , г); вернуться new_rt; } // 查询[QL, Qr]中不同元素个数 INT запроса ( INT RT1, INT RT2, INT QL, INT QR, INT л,INT г) { // Е ( "RT1:% d RT2:% дк:% дл:% дг:% d", RT1, RT2, K, L, г); если (QL <= л && г <= дг) возврата суммы [RT2] - сумма [RT1]; Int середине = (L + R) >> 1 ; INT ANS = 0 ; если (QL <= середина) ANS + = запрос (ЖЙ [RT1], ЖЙ [RT2], QL, Qr, л, средний); если (дг> середина) ANS + = запрос (гс [RT1], гс [RT2], QL, Qr, середина + 1 , г); вернуться анс; } Недействительный print_debug () { Е ( " node_cnt:% d \ п " , node_cnt); для ( INT I = 0 ; я <= node_cnt; я ++ ) Е ( " % D ЖХ:% d гс:% d сумма:% d \ N " , я, LC [I], гс [I], сумма [я ]); } INT основных () { INT Т; зсапЕ ( " % d " , & Т); в то время как (T-- ) { зсапЕ ( " % d% d " , & п, & м); node_cnt = 0 ; построить (Rt [ 0 ], 1 , диапазон); для (INT I = 1. , я <= п, я ++ ) { INT TMP; Scanf ( " % D " , & TMP); RT [I] = Изменить (RT [I - 1. ], TMP, 1. , диапазон); // только изменен на основе версии этого } INT АНС = 0 ; для ( INT I = 0 ; I <т, я ++ ) { INT L, R & л, Р, к; Scanf ( " % D% D% D% D " , & L, R & л &, & Р, & К); Ь^ = Анс; R ^ = анс; р ^ = анс; К ^ = анс; если (л> г) замены (L, R); INT L = 0 , R = диапазон; // в то время как (L <= R) { INT М = L + (RL) / 2 ; если (запрос (к.т. [l- 1 ], к.т. [г], не более ( 1 , пМ), мин (р + М, диапазон), 1 , диапазон)> = к) { ANS = М; R = М- 1 ; } остальное L = М + 1 ; } Е ( " % d \ п " , ANS); } } } [Копировать в буфер] [Сохранить в файл]
Справочные ссылки:
1. https://blog.csdn.net/birdmanqin/article/details/97964662