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
| #include<cstdio> #define MAX 100001 #define BIG 19
long seg[BIG][MAX],val[MAX],m,n,x,y,rank; struct Node{ long left,right,mid; }tr[2*MAX+MAX/2]; void build(long index,long l,long r,long deep){ tr[index].left=l; tr[index].right=r; tr[index].mid=(l+r)>>1; if(l==r){ seg[deep][l]=val[l]; return ; } build(index<<1,l,tr[index].mid,deep+1); build((index<<1)+1,tr[index].mid+1,r,deep+1); long mid=(l+r)>>1,ln=l,rn=mid+1,pos=l; while(ln<=mid && rn<=r){ if(seg[deep+1][ln]>seg[deep+1][rn]) seg[deep][pos++]=seg[deep+1][rn++]; else seg[deep][pos++]=seg[deep+1][ln++]; } if(ln==mid+1) while(rn<=r) seg[deep][pos++]=seg[deep+1][rn++]; else while(ln<=mid) seg[deep][pos++]=seg[deep+1][ln++]; } long bigger(long index,long find,long deep){ if(tr[index].left==tr[index].right){ if(find>seg[deep][tr[index].mid]) return tr[index].mid+1; else return tr[index].mid;} if(find<=seg[deep][tr[index].mid]) return bigger(index<<1,find,deep); if(find>seg[deep][tr[index].mid]) return bigger((index<<1)+1,find,deep); } long Rank(long index,long find,long deep){ if(x<=tr[index].left && tr[index].right<=y) return bigger(index,find,deep)-tr[index].left; long Find=0; if(x<=tr[index].mid) Find+=Rank(index<<1,find,deep+1); if(y>tr[index].mid) Find+=Rank((index<<1)+1,find,deep+1); return Find; } inline long query(){ long left=1,right=n,mid,rend; while(left<right){ mid=(left+right+1)>>1; rend=Rank(1,seg[1][mid],1); if(rend<rank) left=mid; else right=mid-1; } return left; } int main(){ scanf("%ld%ld",&n,&m); for(int i=1;i<=n;i++) scanf("%ld",&val[i]); build(1,1,n,1); while(m--){ scanf("%ld%ld%ld",&x,&y,&rank); printf("%ld\n",seg[1][query()]); } return 0; }
|