题目:http://poj.org/problem?id=2761题意:有n个数,给m个区间,求这m个区间的地K大值思路:裸划分树,与2104相同~~#include <stdio.h>#include <iostream>#include <algorithm>using namespace std;const int maxn=100000;int n, m, a, b, c;int sorted[maxn+10], array[40][maxn+10], num[40][maxn+10];void BuildTree(int v, int left, int right){ if (left==right) return; int mid=(left+right)>>1; int lchild=left, rchild=mid+1; int isame=mid-left+1, same=0; for (int i=left; i<=right; i++) if (array[v][i]<sorted[mid]) isame--; for (int i=left; i<=right; i++) { if (i==left) num[v][i]=0; else num[v][i]=num[v][i-1]; if (array[v][i]<sorted[mid]) { num[v][i]++; array[v+1][lchild++]=array[v][i]; } else if (array[v][i]>sorted[mid]) array[v+1][rchild++]=array[v][i]; else { if (same<isame) { same++; num[v][i]++; array[v+1][lchild++]=array[v][i]; } else array[v+1][rchild++]=array[v][i]; } } BuildTree(v+1, left, mid); BuildTree(v+1, mid+1, right);}int Query(int l, int r, int k, int v, int left, int right){ if (left==right) return array[v][l]; int mid=(left+right)>>1; int s, ss, b, bb; if (l==left) { s=num[v][r]; ss=0; } else { s=num[v][r]-num[v][l-1]; ss=num[v][l-1]; } if (s>=k) { l=left+ss; r=left+ss+s-1; return Query(l, r, k, v+1, left, mid); } else { b=l-left-ss; bb=r-l-s+1; l=mid+b+1; r=mid+b+bb; return Query(l, r, k-s, v+1, mid+1, right); }}int main(){ //freopen("in.txt", "r", stdin); while (scanf("%d %d", &n, &m)==2) { for (int i=1; i<=n; i++) { scanf("%d", &sorted[i]); array[1][i]=sorted[i]; } sort(sorted+1, sorted+1+n); BuildTree(1, 1, n); for (int i=0; i<m; i++) { scanf("%d %d %d", &a, &b, &c); printf("%d\n", Query(a, b, c, 1, 1, n)); } } return 0;}