求区间第k大数...想用二分答案然后块状链表做...超时了..仔细一算时间复杂度好像的确不大够..时间复杂度为每次查询log(10^9)*n^(1/2)*log(n^(1/2))=76800,5000次查询复杂度就到10^8级别了...
明天再用划分树写下这道题...
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int SIZE=300;
int a[100100];
int b[100100];
int n,m;
int find(int l,int r,int x) {
if (b[l]>x) return 0;
int s=l;
while (l!=r) {
int t=(l+r)/2+1;
if (b[t]<=x) l=t;
else r=t-1;
}
return l-s+1;
}
int getnum(int l,int r,int t) {
int ans=0,i;
for (i=l;i%SIZE!=1&&i<=r;i++) {
if (a[i]<=t) ans++;
}
for (;i+SIZE<=r;i+=SIZE) {
ans+=find(i,i+SIZE-1,t);
}
for (;i<=r;i++) {
if (a[i]<=t) ans++;
}
//printf("%d %d %d %d\n",l,r,t,ans);
return ans;
}
int main() {
int x,y,z,i;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++) {
scanf("%d",&a[i]);
b[i]=a[i];
}
for (i=1;i<=n;i+=SIZE) {
sort(b+i,b+min(i+SIZE,n+1));
}
for (i=0;i<m;i++) {
scanf("%d%d%d",&x,&y,&z);
int l=-1000000100,r=1000000100;
while (l!=r) {
int t=(l+r)/2;
if (getnum(x,y,t)<z) l=t+1;
else r=t;
}
printf("%d\n",l);
}
return 0;
}