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