原题网址:http://poj.org/problem?id=2104
//#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
const int N = 1e5 + 10;
template <typename T> void read (T &x){
x = 0; int f = 1;
char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f *= -1; c = getchar();}
while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
x *= f;
}
int n,m,a[N],b[N],c[N],root[N],lc[20*N],rc[20*N],sum[20*N],s;
int tra(int x){
int l = 1, r = n;
while (l < r){
int mid = (l + r + 1) >> 1;
if (b[mid] <= x)
l = mid;
else
r = mid - 1;
}
return c[l];
}
int detra(int x){
int l = 1, r = n;
while (l < r){
int mid = (l + r + 1) >> 1;
if (c[mid] <= x)
l = mid;
else
r = mid - 1;
}
return b[l];
}
void init(int i,int l, int r){
sum[i] = 0;
if (l == r) return;
lc[i] = ++s; init(lc[i],l,(l+r)/2);
rc[i] = ++s; init(rc[i],(l+r)/2+1,r);
}
void add(int i, int last, int l, int r, int c){
sum[i] = sum[last] + 1;
if (l == r) return;
if (c <= (l+r)/2){
rc[i] = rc[last];
lc[i] = ++s;
add(lc[i],lc[last],l,(l+r)/2,c);
}else{
lc[i] = lc[last];
rc[i] = ++s;
add(rc[i],rc[last],(l+r)/2+1,r,c);
}
}
int qry(int i, int last, int l, int r, int k){
if (l == r) return l;
if (sum[lc[i]] - sum[lc[last]] >= k)
return qry(lc[i],lc[last],l,(l+r)/2,k);
else
return qry(rc[i],rc[last],(l+r)/2+1,r,k - (sum[lc[i]] - sum[lc[last]]));
}
int main(){
//printf("%.6f\n",sizeof(root)*3.0/1024/1024);
//freopen("tree.in","r",stdin);
//freopen("tree.out","w",stdout);
int T;
T = 1;//read(T);
while (T--){
read(n);read(m);
init(root[0] = s = 0,1,n);
for (int i=1; i<=n; i++)
read(a[i]),
b[i] = a[i];
std::sort(b+1,b+n+1);
c[1] = 1;
for (int i=2; i<=n; i++)
c[i] = c[i - 1] + (b[i] > b[i - 1]);
for (int i=1; i<=n; i++)
add(root[i] = ++s,root[i - 1],1,n,tra(a[i]));
int l,r,k;
while (m--){
read(l);read(r);read(k);
printf("%d\n",detra(qry(root[r],root[l - 1],1,n,k/*r-l+2-k*/)));
}
}
//fprintf(stderr,"Elapsed time:%.3f secs.\n",(double)clock()/CLOCKS_PER_SEC);
return 0;
}
吐槽一开始用指针写被Poj卡时间,被Hdu卡空间,Hdu题面还写错mdzz。
以下被卡版本:
//#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
const int N = 1e5 + 10;
template <typename T> void read (T &x){
x = 0; int f = 1;
char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f *= -1; c = getchar();}
while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
x *= f;
}
int n,m,a[N],b[N],c[N];
int tra(int x){
int l = 1, r = n;
while (l < r){
int mid = (l + r + 1) >> 1;
if (b[mid] <= x)
l = mid;
else
r = mid - 1;
}
return c[l];
}
int detra(int x){
int l = 1, r = n;
while (l < r){
int mid = (l + r + 1) >> 1;
if (c[mid] <= x)
l = mid;
else
r = mid - 1;
}
return b[l];
}
struct node{
int l,r,sum;
node *lc,*rc;
void init(int _l, int _r){
l=_l;r=_r;sum=0;
if (l == r) return;
lc=new(node), lc->init(l,(l+r)/2);
rc=new(node), rc->init((l+r)/2+1,r);
}
void add(node *last, int c){
sum++;
if (l == r) return;
if (c <= lc->r){
lc=new(node);
last=last->lc;
*lc = *last;
lc->add(last,c);
}else{
rc=new(node);
last=last->rc;
*rc = *last;
rc->add(last,c);
}
}
int qry(node *last, int k){
if (l == r) return l;
if (lc->sum - last->lc->sum >= k)
return lc->qry(last->lc,k);
else
return rc->qry(last->rc,k-(lc->sum - last->lc->sum));
}
};
node root[N];
int main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
//read(n);read(m);
scanf("%d%d",&n,&m);
root[0].init(1,n);
for (int i=1; i<=n; i++)
scanf("%d",&a[i]),
//read(a[i]),
b[i] = a[i];
std::sort(b+1,b+n+1);
c[1] = 1;
for (int i=2; i<=n; i++)
c[i] = c[i - 1] + (b[i] > b[i - 1]);
for (int i=1; i<=n; i++)
root[i] = root[i - 1],
root[i].add(&root[i - 1],tra(a[i]));
int l,r,k;
while (m--){
//read(l);read(r);read(k);
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",detra(root[r].qry(&root[l - 1],k)));
}
//fprintf(stderr,"Elapsed time:%.3f secs.\n",(double)clock()/CLOCKS_PER_SEC);
return 0;
}