上次就听岐哥讲了树状数组如何高效求第k大的数,一直没去敲,今天早上起来睡不着就敲了下了,也是看的岐哥的博客才完全搞明白的
http://www.cnblogs.com/wuyiqi/archive/2011/12/25/2301071.html
int findkth(int k) {
int i, cnt = 0, ans = 0;
for(i = 20;i >= 0; i--) {
ans += (1<<i);
if(ans >= n || cnt+node[ans] >= k)
ans -= (1<<i);
else
cnt += node[ans];
}
return ans+1;
}
核心代码就是这一块,上面博客有很详细的解释!
#include <stdio.h> #include <algorithm> #define lowbit(x) ((x)&(-x)) using namespace std; struct QQ { int l, r, k, id; bool operator < (const QQ &a) const { if(l == a.l) return r < a.r; return l < a.l; } }a[50005]; struct PP { int val, id; bool operator < (const PP &a) const { return val < a.val; } }b[100005]; int node[100005], ans[50005], fval[100005], pval[100005], n; void add(int x, int val) { if(x == 0) return ; while(x <= n) { node[x] += val; x += lowbit(x); } } int findkth(int k) { int i, cnt = 0, ans = 0; for(i = 20;i >= 0; i--) { ans += (1<<i); if(ans >= n || cnt+node[ans] >= k) ans -= (1<<i); else cnt += node[ans]; } return ans+1; } int max(int a, int b) { return a > b ? a : b; } void init() { memset(node, 0, sizeof(node)); } int main () { int m, i, j; while(scanf("%d%d", &n, &m) != -1) { init(); for(i = 1;i <= n ;i++) { scanf("%d", &b[i].val); b[i].id = i; } sort(b+1, b+n+1); int k = 1; fval[b[1].id] = 1; pval[1] = b[1].val; for(i = 2;i <= n; i++) { if(b[i].val != b[i-1].val) pval[++k] = b[i].val; fval[b[i].id] = k; } for(i = 0;i < m; i++) { scanf("%d%d%d", &a[i].l, &a[i].r, &a[i].k); if(a[i].r < a[i].l) swap(a[i].l, a[i].r); a[i].id = i; } sort(a, a+m); int curl = 1; int curr = 0; for(i = 0;i < m; i++) { if(curr < a[i].l) { for(j = curl;j <= curr; j++) add(fval[j], -1); for(j = a[i].l;j <= a[i].r; j++) add(fval[j], 1); curl = a[i].l; curr = a[i].r; } else { for(j = curl;j < a[i].l; j++) add(fval[j], -1); for(j = curr+1;j <= a[i].r; j++) add(fval[j], 1); curl = a[i].l; curr = a[i].r; } ans[a[i].id] = pval[findkth(a[i].k)]; } for(i = 0;i < m; i++) printf("%d\n", ans[i]); } return 0; }