hdu 4251 划分树入门题
来源:互联网 发布:如何复制淘宝上的图片 编辑:程序博客网 时间:2024/05/21 19:31
题意:
给n个数字的数组,m个操作,操作输入fr,to。
每次操作求fr,to范围内的中位数。
解析:
把求区间的第k大数转换成了中位数。
中位数是 第 ((to - fr) >> 1) + 1 大数。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <set>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1e5 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int tree[30][maxn]; //表示每层每个位置的值int sorted[maxn]; //排完序的数int toleft[30][maxn]; //toleft[p][i]表示第p层从1到i有多少个数在左边void build(int l, int r, int dep){ if (l == r) return; int mi = (l + r) >> 1; int same = mi - l + 1; //等于中位数的数字个数 for (int i = l; i <= r; i++) { if (tree[dep][i] < sorted[mi]) { same--; } } int lpos = l; int rpos = mi + 1; for (int i = l; i <= r; i++) { if (tree[dep][i] < sorted[mi])//比中位数小 { tree[dep + 1][lpos++] = tree[dep][i]; } else if (tree[dep][i] == sorted[mi] && 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; // - l 不是减一 } build(l, mi, dep + 1); build(mi + 1, r, dep + 1);}//查询区间第k大数int query(int L, int R, int l, int r, int dep, int k){ if (l == r) return tree[dep][l]; int mi = (L + R) >> 1; int cnt = toleft[dep][r] - toleft[dep][l - 1]; if (k <= cnt) { int nextl = L + toleft[dep][l - 1] - toleft[dep][L - 1]; int nextr = nextl + cnt - 1; return query(L, mi, nextl, nextr, dep + 1, k); } else { int nextr = r + toleft[dep][R] - toleft[dep][r]; int nextl = nextr - (r - l - cnt); return query(mi + 1, R, nextl, nextr, dep + 1, k - cnt); }}int main(){ #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAL int n, m; int ca = 1; while (~scanf("%d", &n)) { memset(tree, 0, sizeof(tree)); memset(toleft, 0, sizeof(toleft)); for (int i = 1; i <= n; i++)//start from 1 { scanf("%d", &tree[0][i]); sorted[i] = tree[0][i]; } sort(sorted + 1, sorted + n + 1); build(1, n, 0); scanf("%d", &m); printf("Case %d:\n", ca++); while (m--) { int fr, to; scanf("%d%d", &fr, &to); printf("%d\n", query(1, n, fr, to, 0, ((to - fr) >> 1) + 1)); } } return 0;}
0 0
- hdu 4251 划分树入门题
- HDU 4251 划分树
- hdu 4251 划分树
- HDU 4251 划分树
- hdu 4251 划分树
- poj 2104 and hdu 2665 划分树模板入门题
- hdu 4251 划分树(板子题)
- HDU 2665 Kth number(划分树入门题,纯套模板)
- poj2104K-th Number【划分树入门题】
- 划分树入门
- 【划分树】HDU 3473
- hdu 3473 划分树
- HDU 2665 划分树
- hdu 3473 划分树
- HDU 3727 划分树
- hdu 2665 划分树
- hdu 划分树
- hdu 2665 划分树
- 2.16-switch
- Unity 之 C# 利用回调函数实现C++匿名函数
- 课堂笔记03
- Android控件开发之CheckBox
- linux input子系统(一)
- hdu 4251 划分树入门题
- Android唤醒锁问题
- Maven Unable to locate the Javac Compiler
- 2.17-switch练习
- contentType,charset和pageEncoding的区别
- 关于java项目路径问题
- mysql的InnoDB参数详解
- 快搜搜:2015年应届生怎么找工作?
- Hibernate4 用Discriminator之后 select问题