划分树 POJ 2761 feed the dogs

来源:互联网 发布:linux 没有rc.d 编辑:程序博客网 时间:2024/06/05 23:45

题目链接:http://poj.org/problem?id=2761

代码风格:notonlysuccess划分树http://www.notonlysuccess.com/index.php/divide-tree/

上面的网站对划分树有相当详细的说明~~不再赘述


题目大意: 有n只小狗,每个小狗有一个相对的魅力值,求第i只小狗~第j只小狗中魅力值第k大的那个小狗的魅力值是多少(即求区间[i, j]第k大的数)

直接附上代码:

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;#define lson l, m, rt << 1#define rson m+1, r, rt << 1 | 1#define mid int m = (l+r) >> 1struct nod{int l, r;}p[1345678];int val[20][200002];int w[1898989];int tol[20][200020];void build(int l, int r, int rt, int ss){p[rt].l = l;p[rt].r = r;if(l == r)return ;mid ;int lsame = m - l + 1;int i;for(i = l; i <= r; i ++)if(val[ss][i] < w[m])lsame --;int lpos = l ;int rpos = m+1;int same = 1;for(i = l; i <= r; i ++){if(l == i)tol[ss][i] = 0;else tol[ss][i] = tol[ss][i-1];if(val[ss][i] < w[m]){tol[ss][i] ++;val[ss+1][lpos ++] = val[ss][i];}else if(val[ss][i] > w[m]){val[ss+1][rpos ++] = val[ss][i];}else{if(same <= lsame){tol[ss][i] ++;val[ss+1][lpos ++] = val[ss][i];same ++;}else {val[ss+1][rpos ++] = val[ss][i];}}}build(lson, ss+1);build(rson, ss+1);}int query(int k, int l, int r, int rt, int d){if(l == r)return val[d][l];int s, ss;if(l == p[rt].l ){s = tol[d][r];ss = 0;}else {s = tol[d][r] - tol[d][l-1];ss = tol[d][l-1];}if(k <= s){int newl = ss + p[rt].l;int newr = ss + p[rt].l + s - 1;return query(k, newl, newr, rt << 1, d+1);}else{int b = r-l+1-s;int bb = l - p[rt].l - ss;int m = (p[rt].l + p[rt].r ) >> 1;int newl = bb + m + 1;int newr = bb + m + b;return query(k-s, newl, newr, rt << 1 | 1, d + 1);}}int main(){int n, m;int a, b, c;while(scanf("%d%d", &n, &m) != EOF){int i;for(i = 1; i <= n; i ++){scanf("%d", &w[i]);val[0][i] = w[i];}sort(w+1, w+n+1);build(1, n, 1, 0);while(m --){scanf("%d%d%d", &a, &b, &c);int k ;if(a <= b)k = query(c, a, b, 1, 0);else k = query(c, b, a, 1, 0);printf("%d\n", k);}}return 0;}


原创粉丝点击