首页 > 代码库 > 划分树
划分树
POJ 2214 裸的划分树求区间第k大值
//POJ 2104#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#define maxn 100010using namespace std;int tree[30][maxn];int sorted[maxn];int toleft[30][maxn];void build(int l, int r, int dep) { if (l == r) return; int mid = (l+r) >> 1; int same = mid - l + 1; for (int i=l; i<=r; ++i) if (tree[dep][i] < sorted[mid]) same--; int lpos = l; int rpos = mid+1; for (int i=l; i<=r; ++i) { if (tree[dep][i] < sorted[mid]) tree[dep+1][lpos++] = tree[dep][i]; else if (tree[dep][i] == sorted[mid] && same>0) { tree[dep+1][lpos++] = tree[dep][i]; same--; }else tree[dep+1][rpos++] = tree[dep][i]; toleft[dep][i] = toleft[dep][l-1]+lpos-l; } build(l, mid, dep+1); build(mid+1, r, dep+1);}int query(int L, int R, int l, int r, int dep, int k) { if (l == r) return tree[dep][l]; int mid = (L+R)>>1; int cnt = toleft[dep][r] - toleft[dep][l-1]; if (cnt >= k) { int newl = L+toleft[dep][l-1]-toleft[dep][L-1]; int newr = newl+cnt-1; return query(L, mid, newl, newr, dep+1, k); }else { int newr = r+toleft[dep][R]-toleft[dep][r]; int newl = newr-(r-l-cnt); return query(mid+1, R, newl, newr, dep+1, k-cnt); }}int main() { // freopen("in.cpp", "r", stdin); int n, m; while(~scanf("%d%d", &n, &m)) { for (int i=1; i<=n; ++i) { scanf("%d", &tree[0][i]); sorted[i] = tree[0][i]; } sort(sorted+1, sorted+1+n); build(1, n, 0); while(m--) { int a, b, c; scanf("%d%d%d", &a, &b, &c); printf("%d\n", query(1, n, a, b, 0, c)); } } return 0;}
HDU 4417 二分+划分树
//HDU 4417#include <stdio.h>#include <string.h>#include <algorithm>#include <iostream>using namespace std;const int maxn = 1e5+10;int tree[30][maxn];int toleft[30][maxn];int sorted[maxn];void build(int l, int r, int dep) { if (l == r) return; int mid = (l+r) >> 1; int same = mid - l + 1; for (int i=l; i<=r; ++i) if (tree[dep][i] < sorted[mid]) same--; int lpos = l; int rpos = mid+1; for (int i=l; i<=r; ++i) { if (tree[dep][i] < sorted[mid]) tree[dep+1][lpos++] = tree[dep][i]; else if (tree[dep][i] == sorted[mid] && same>0) { tree[dep+1][lpos++] = tree[dep][i]; same--; }else tree[dep+1][rpos++] = tree[dep][i]; toleft[dep][i] = toleft[dep][l-1]+lpos-l; } build(l, mid, dep+1); build(mid+1, r, dep+1);}int query(int L, int R, int l, int r, int dep, int k) { if (l == r) return tree[dep][l]; int mid = (L+R)>>1; int cnt = toleft[dep][r] - toleft[dep][l-1]; if (cnt >= k) { int newl = L+toleft[dep][l-1]-toleft[dep][L-1]; int newr = newl+cnt-1; return query(L, mid, newl, newr, dep+1, k); }else { int newr = r+toleft[dep][R]-toleft[dep][r]; int newl = newr-(r-l-cnt); return query(mid+1, R, newl, newr, dep+1, k-cnt); }}int solve(int n, int a, int b, int c) { int ans = 0; int l = 1; int r = b - a + 1; int mid; while(l<=r) { mid = (l+r)>>1; int temp = query(1, n, a, b, 0, mid); if (temp <= c) { l = mid+1; ans = mid; }else r = mid - 1; } return ans;}int main() { // freopen("in.cpp", "r", stdin); int t; int k = 0; scanf("%d", &t); while(t--) { int n, m; scanf("%d%d", &n, &m); memset(toleft, 0, sizeof(toleft)); memset(tree, 0, sizeof(tree)); for (int i=1; i<=n; ++i) { scanf("%d", &tree[0][i]); sorted[i] = tree[0][i]; } sort(sorted+1, sorted+1+n); build(1, n, 0); printf("Case %d:\n", ++k); for (int i=0; i<m; ++i) { int a, b, c; scanf("%d%d%d",&a, &b, &c); a++; b++; int ans = solve(n, a, b, c); printf("%d\n", ans); } } return 0;}
划分树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。