HDU 2665
2014-04-30 18:36
281 查看
思路:划分树
#include<iostream> #include<algorithm> #include<cstdio> #define MAX 100005 using namespace std; class TreeNode { public: int left, right, mid; }; TreeNode node[4*MAX]; int val[30][MAX]; int ToLeft[30][MAX]; int sorted[MAX]; void BuildTree(int k, int d, int l, int r) { node[k].left = l; node[k].right = r; node[k].mid = (l + r) >> 1; if(l == r) return ; int mid = (l + r) >> 1; int lsame = mid - l + 1; for(int i = l;i <= r;i ++) { if(val[d][i] < sorted[mid]) lsame --; } int lpos = l; int rpos = mid + 1; for(int i = l;i <= r;i ++) { if(i == l) ToLeft[d][i] = 0; else ToLeft[d][i] = ToLeft[d][i-1]; if(val[d][i] < sorted[mid]) { ToLeft[d][i] ++; val[d+1][lpos ++] = val[d][i]; } else if(val[d][i] > sorted[mid]) { val[d+1][rpos ++] = val[d][i]; } else { if(lsame) { ToLeft[d][i] ++; val[d+1][lpos ++] = val[d][i]; lsame --; } else val[d+1][rpos ++] = val[d][i]; } } BuildTree(k << 1, d+1, l, mid); BuildTree(k << 1|1, d+1, mid + 1, r); } int Query(int l, int r, int k, int d, int idx) { if(l == r) return val[d][l]; int s; int ss; if(l == node[idx].left) { s = ToLeft[d][r]; ss = 0; } else { s = ToLeft[d][r] - ToLeft[d][l-1]; ss = ToLeft[d][l-1]; } if(s >= k) { int newl = node[idx].left + ss; int newr = node[idx].left + ss + s - 1; return Query(newl, newr, k, d + 1, idx << 1); } else { int mid = node[idx].mid; int b = r - l - s + 1; int bb = l - node[idx].left - ss; int newl = mid + bb + 1; int newr = mid + bb + b; return Query(newl, newr, k - s, d + 1, idx << 1|1); } } int main(int argc, char const *argv[]) { int c, n, m, l, r, k; //freopen("in.c", "r", stdin); scanf("%d", &c); while(c--) { scanf("%d%d", &n, &m); for(int i = 1;i <= n;i ++) { scanf("%d", &val[0][i]); sorted[i] = val[0][i]; } sort(sorted + 1, sorted + n + 1); BuildTree(1, 0, 1, n); for(int i = 0; i< m;i ++) { scanf("%d%d%d", &l, &r, &k); printf("%d\n", Query(l, r, k, 0, 1)); } } return 0; }