#define PROBLEM "https://judge.yosupo.jp/problem/range_kth_smallest"
#include"data_structure/bst/persistent_treap.hpp"#include<algorithm>
#include<iostream>
#include<vector>// Fast I/Ovoidfast_io(){std::ios_base::sync_with_stdio(false);std::cin.tie(NULL);}intmain(){fast_io();intN,Q;std::cin>>N>>Q;std::vector<int>a(N);std::vector<int>distinct_elements;for(inti=0;i<N;++i){std::cin>>a[i];distinct_elements.push_back(a[i]);}// Coordinate Compressionstd::sort(distinct_elements.begin(),distinct_elements.end());distinct_elements.erase(std::unique(distinct_elements.begin(),distinct_elements.end()),distinct_elements.end());autoget_compressed_rank=[&](intval){returnstd::lower_bound(distinct_elements.begin(),distinct_elements.end(),val)-distinct_elements.begin();};// Build a persistent treap for each prefix of the arraystd::vector<m1une::persistent_treap<int>>versions(N+1);for(inti=0;i<N;++i){versions[i+1]=versions[i].insert(get_compressed_rank(a[i]));}for(intq=0;q<Q;++q){intl,r,k;std::cin>>l>>r>>k;// Meguru-style Binary Search// We are looking for the smallest rank 'ok' such that the number of elements// in a[l..r-1] with rank <= 'ok' is strictly greater than k.intng=-1;// 'ng' is a rank that is always "not good enough"intok=distinct_elements.size()-1;// 'ok' is a rank that is "good enough"while(std::abs(ok-ng)>1){intmid=ng+(ok-ng)/2;// Count elements in the range a[l..r-1] with a compressed rank <= midintcount_le=versions[r].order_of_key(mid+1)-versions[l].order_of_key(mid+1);if(count_le>k){// mid is a possible answer, try for a smaller oneok=mid;}else{// mid is not the answer, we need a larger rankng=mid;}}// The answer is the original value corresponding to the 'ok' rankstd::cout<<distinct_elements[ok]<<"\n";}return0;}
#line 1 "verify/unit_test/persistent_treap.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/range_kth_smallest"
#line 1 "data_structure/bst/persistent_treap.hpp"
#include<algorithm>
#include<ctime>
#include<iostream>
#include<memory>
#include<optional>
#include<random>namespacem1une{template<typenameT>structpersistent_treap{private:structnode{T_key;int_priority;std::shared_ptr<node>_l,_r;int_count;node(Tkey):_key(key),_priority(rand()),_l(nullptr),_r(nullptr),_count(1){}};std::shared_ptr<node>_root;intcount(std::shared_ptr<node>t){returnt?t->_count:0;}voidupdate_count(std::shared_ptr<node>t){if(t){t->_count=1+count(t->_l)+count(t->_r);}}voidsplit(std::shared_ptr<node>t,Tkey,std::shared_ptr<node>&l,std::shared_ptr<node>&r){if(!t){l=r=nullptr;return;}if(key<t->_key){autonew_node=std::make_shared<node>(*t);split(new_node->_l,key,l,new_node->_l);r=new_node;update_count(r);}else{autonew_node=std::make_shared<node>(*t);split(new_node->_r,key,new_node->_r,r);l=new_node;update_count(l);}}std::shared_ptr<node>merge(std::shared_ptr<node>l,std::shared_ptr<node>r){if(!l||!r)returnl?l:r;if(l->_priority>r->_priority){autonew_node=std::make_shared<node>(*l);new_node->_r=merge(new_node->_r,r);update_count(new_node);returnnew_node;}else{autonew_node=std::make_shared<node>(*r);new_node->_l=merge(l,new_node->_l);update_count(new_node);returnnew_node;}}std::shared_ptr<node>insert_impl(std::shared_ptr<node>t,std::shared_ptr<node>item){if(!t)returnitem;if(item->_priority>t->_priority){split(t,item->_key,item->_l,item->_r);update_count(item);returnitem;}autonew_node=std::make_shared<node>(*t);if(item->_key<new_node->_key){new_node->_l=insert_impl(new_node->_l,item);}else{new_node->_r=insert_impl(new_node->_r,item);}update_count(new_node);returnnew_node;}std::shared_ptr<node>erase_impl(std::shared_ptr<node>t,Tkey){if(!t)returnnullptr;if(t->_key==key)returnmerge(t->_l,t->_r);autonew_node=std::make_shared<node>(*t);if(key<new_node->_key){new_node->_l=erase_impl(new_node->_l,key);}else{new_node->_r=erase_impl(new_node->_r,key);}update_count(new_node);returnnew_node;}Tfind_by_order_impl(std::shared_ptr<node>t,intk){if(!t)returnT();intleft_count=count(t->_l);if(k<left_count)returnfind_by_order_impl(t->_l,k);if(k==left_count)returnt->_key;returnfind_by_order_impl(t->_r,k-left_count-1);}intorder_of_key_impl(std::shared_ptr<node>t,Tkey){if(!t)return0;if(key<=t->_key)returnorder_of_key_impl(t->_l,key);returncount(t->_l)+1+order_of_key_impl(t->_r,key);}std::optional<T>lower_bound_impl(std::shared_ptr<node>t,Tkey){if(!t)returnstd::nullopt;if(key<=t->_key){autores=lower_bound_impl(t->_l,key);returnres.has_value()?res:t->_key;}returnlower_bound_impl(t->_r,key);}std::optional<T>upper_bound_impl(std::shared_ptr<node>t,Tkey){if(!t)returnstd::nullopt;if(key<t->_key){autores=upper_bound_impl(t->_l,key);returnres.has_value()?res:t->_key;}returnupper_bound_impl(t->_r,key);}public:persistent_treap():_root(nullptr){srand(time(NULL));}persistent_treap(std::shared_ptr<node>root):_root(root){}persistent_treapinsert(Tkey){returnpersistent_treap(insert_impl(_root,std::make_shared<node>(key)));}persistent_treaperase(Tkey){returnpersistent_treap(erase_impl(_root,key));}Tfind_by_order(intk){returnfind_by_order_impl(_root,k);}intorder_of_key(Tkey){returnorder_of_key_impl(_root,key);}std::optional<T>lower_bound(Tkey){returnlower_bound_impl(_root,key);}std::optional<T>upper_bound(Tkey){returnupper_bound_impl(_root,key);}intsize(){returncount(_root);}};}// namespace m1une#line 4 "verify/unit_test/persistent_treap.test.cpp"
#line 7 "verify/unit_test/persistent_treap.test.cpp"
#include<vector>// Fast I/Ovoidfast_io(){std::ios_base::sync_with_stdio(false);std::cin.tie(NULL);}intmain(){fast_io();intN,Q;std::cin>>N>>Q;std::vector<int>a(N);std::vector<int>distinct_elements;for(inti=0;i<N;++i){std::cin>>a[i];distinct_elements.push_back(a[i]);}// Coordinate Compressionstd::sort(distinct_elements.begin(),distinct_elements.end());distinct_elements.erase(std::unique(distinct_elements.begin(),distinct_elements.end()),distinct_elements.end());autoget_compressed_rank=[&](intval){returnstd::lower_bound(distinct_elements.begin(),distinct_elements.end(),val)-distinct_elements.begin();};// Build a persistent treap for each prefix of the arraystd::vector<m1une::persistent_treap<int>>versions(N+1);for(inti=0;i<N;++i){versions[i+1]=versions[i].insert(get_compressed_rank(a[i]));}for(intq=0;q<Q;++q){intl,r,k;std::cin>>l>>r>>k;// Meguru-style Binary Search// We are looking for the smallest rank 'ok' such that the number of elements// in a[l..r-1] with rank <= 'ok' is strictly greater than k.intng=-1;// 'ng' is a rank that is always "not good enough"intok=distinct_elements.size()-1;// 'ok' is a rank that is "good enough"while(std::abs(ok-ng)>1){intmid=ng+(ok-ng)/2;// Count elements in the range a[l..r-1] with a compressed rank <= midintcount_le=versions[r].order_of_key(mid+1)-versions[l].order_of_key(mid+1);if(count_le>k){// mid is a possible answer, try for a smaller oneok=mid;}else{// mid is not the answer, we need a larger rankng=mid;}}// The answer is the original value corresponding to the 'ok' rankstd::cout<<distinct_elements[ok]<<"\n";}return0;}