1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include <cstdio> #include <cctype> #include <algorithm> using namespace std; const int Mn(200500);
void qread(int &x) { x = 0; int o(1); char c=getchar(); while(!isdigit(c)) { if(c=='-') o=-1; c = getchar(); } while(isdigit(c)) { x = x*10 + c-'0'; c = getchar(); } x *= o; }
int a[Mn],vals[Mn];
struct CTree_node { int l,r,v; CTree_node *ls,*rs; }*ver[Mn],*null;
void init_null() { null = new CTree_node(); null->ls = null->rs = null; } void build(int l,int r,CTree_node* &p) { p = new CTree_node(); p->l = l; p->r = r; if(l==r) { p->ls = p->rs = null; return; } int mid((l+r)>>1); build(l,mid,p->ls); build(mid+1,r,p->rs); } void modify(CTree_node* last_ver,CTree_node* &mod_ver,int p) { mod_ver = new CTree_node(); *mod_ver = *last_ver; ++(mod_ver->v); if(mod_ver->l==mod_ver->r) return; if(mod_ver->ls->r >= p) modify(last_ver->ls,mod_ver->ls,p); else modify(last_ver->rs,mod_ver->rs,p); } int query(CTree_node* ltree,CTree_node* rtree,int k) { int lv = rtree->ls->v - ltree->ls->v; if(ltree->l==ltree->r) return vals[ltree->l]; if(k<=lv) return query(ltree->ls,rtree->ls,k); else return query(ltree->rs,rtree->rs,k-lv); }
int main() { init_null(); int n,m; qread(n), qread(m); for(int i(1);i<=n;++i) { qread(a[i]); vals[i] = a[i]; } sort(vals+1,vals+n+1); int valn = unique(vals+1,vals+n+1)-vals-1; build(1,valn,ver[0]); for(int i(1);i<=n;++i) { int apos = lower_bound(vals+1,vals+valn+1,a[i])-vals; modify(ver[i-1],ver[i],apos); } while(m--) { int l,r,k; qread(l), qread(r), qread(k); printf("%d\n",query(ver[l-1],ver[r],k)); } return 0; }
|