HDU 4417Super Mario 划分树 + 二分
来源:互联网 发布:mysql update if 编辑:程序博客网 时间:2024/06/13 09:58
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4417
题意:给定一个数组,下标从0开始,然后有一定数量的询问,问给定区间内小于等于给定值得个数
思路:二分枚举第k小值,小于等于给定值时就更新结果为k,二分完毕后输出结果即可
PS:话说当时正在宿舍看这道题,突闻系主任要点名,撒腿就跑,终于及时赶到。。。听所谓企业宣讲时想这道题,首先想到的枚举中位数,可不就是二分么。。。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 100010;struct node{ int l, r;}s[N*4];int n, m;int arr[N], arrs[N], cut[20][N], seg[20][N];void build(int d, int l, int r, int k){ s[k].l = l, s[k].r = r; if(l == r) return; int mid = (l + r) >> 1, cnt = mid - l + 1, lb = l, rb = mid + 1; for(int i = l; i <= mid; i++) if(arrs[i] < arrs[mid]) cnt--; for(int i = l; i <= r; i++) { if(i == l) cut[d][i] = 0; else cut[d][i] = cut[d][i-1]; if(seg[d][i] == arrs[mid]) { if(cnt) cnt--, cut[d][i]++, seg[d+1][lb++] = seg[d][i]; else seg[d+1][rb++] = seg[d][i]; } else if(seg[d][i] < arrs[mid]) cut[d][i]++, seg[d+1][lb++] = seg[d][i]; else seg[d+1][rb++] = seg[d][i]; } build(d + 1, l, mid, k << 1); build(d + 1, mid + 1, r, k << 1|1);}int query(int d, int l, int r, int x, int k){ if(s[k].l == s[k].r) return seg[d][s[k].l]; int mid = (s[k].l + s[k].r) >> 1, ls, lss; if(l == s[k].l) ls = 0, lss = cut[d][r]; else ls = cut[d][l-1], lss = cut[d][r] - ls; if(x <= lss) return query(d + 1, s[k].l + ls, s[k].l + ls + lss - 1, x, k << 1); else return query(d + 1, mid + 1 + l - s[k].l - ls, mid + 1 + r - s[k].l - ls - lss, x - lss, k << 1|1);}int main(){ int t, a, b, c, x = 0; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d", arr + i); seg[0][i] = arrs[i] = arr[i]; } sort(arrs + 1, arrs + 1 + n); build(0, 1, n, 1); printf("Case %d:\n", ++x); while(m--) { scanf("%d%d%d", &a, &b, &c); a++, b++; /*给定的数组和区间都是下标0开始的,我按1开始,因此加1*/ int l = 1, r = b - a + 1, res = 0; while(l <= r) { int mid = (l + r) >> 1; int tmp = query(0, a, b, mid, 1); if(tmp > c) r = mid - 1; else l = mid + 1, res = mid; } printf("%d\n", res); } } return 0;}
0 0
- hdu 4417 Super Mario--二分--划分树
- HDU 4417 Super Mario(划分树+二分)
- HDU-4417-Super Mario(划分树+二分)
- 【划分树+二分】HDU 4417 Super Mario
- HDU 4417Super Mario 划分树 + 二分
- HDU 4417 Super Mario 划分树+二分
- HDU-4417 Super Mario,划分树+二分!
- 【HDU】4417 Super Mario(划分树+二分)
- HDU 4417 Super Mario(划分树+二分)
- HDU 4417-Super Mario(划分树-二分查找)
- hdu 4417 Super Mario (划分树)
- HDU 4417 Super Mario 划分树
- hdu--4417Super Mario+划分树
- hdu 4417 Super Mario(划分树)
- hdu 4417 Super Mario (主席树+二分)
- HDU 4417 Super Mario (树状数组+离线处理)(划分树+二分答案)
- HDU4417 Super Mario(划分树+二分)
- hdu 4417 Super Mario 划分树(线段树)
- Linux的五个查找命令
- 排序七部曲之(五)归并排序
- Problem P
- hdu2552
- Python Enumerate
- HDU 4417Super Mario 划分树 + 二分
- Android 开发资源
- 自己整理的安卓逆向学习路线图
- HDU 4167 User Names
- 【二叉搜索数】HDU3791二叉搜索树
- SimplifyReader源码学习:(一)音乐播放功能总结
- Mac pro安装Ubuntu
- 2016SDAU编程练习三1012
- iOS之单例模式常见写法