HDU 5649 线段树+二分
来源:互联网 发布:手机淘宝怎么比价 编辑:程序博客网 时间:2024/06/05 20:44
题意:
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5649
n个数的排列,两种操作,一种将[L,R]区间内的数递减排序,另一种将[L,R]中的数递增排序,问最后第k个位置的数字是多少。
思路:
好题。
因为最后考虑的只是第k个位置的数字,二分答案。
每次将序列中比x大的都标记为1,其余包括x标记为0,每次排序前,先查询区间中有多少个1和0,然后按照操作将1和0分别更新到区间的左右两部分,用线段树区间更新区间查询即可。判断时如果第k个位置为0则r=m-1,否则l=m+1。
代码:
#include <bits/stdc++.h>using namespace std;#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1const int MAXN = 1e5 + 10;int n, q, k;int a[MAXN], b[MAXN], op[MAXN], LL[MAXN], RR[MAXN];int C[MAXN << 2], lazy[MAXN << 2];void pushUp(int rt) { C[rt] = C[rt << 1] + C[rt << 1 | 1];}void pushDown(int rt, int len) { if (lazy[rt] != -1) { lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt]; C[rt << 1] = (len - (len >> 1)) * lazy[rt]; C[rt << 1 | 1] = (len >> 1) * lazy[rt]; lazy[rt] = -1; }}void build(int l, int r, int rt) { lazy[rt] = -1; if (l == r) { C[rt] = a[l]; return; } int m = (l + r) >> 1; build(lson); build(rson); pushUp(rt);}void update(int L, int R, int v, int l, int r, int rt) { if (L <= l && r <= R) { C[rt] = v * (r - l + 1); lazy[rt] = v; return; } pushDown(rt, r - l + 1); int m = (l + r) >> 1; if (L <= m) update(L, R, v, lson); if (R > m) update(L, R, v, rson); pushUp(rt);}int query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) return C[rt]; pushDown(rt, r - l + 1); int m = (l + r) >> 1, res = 0; if (L <= m) res += query(L, R, lson); if (R > m) res += query(L, R, rson); return res;}int cal(int x) { for (int i = 1; i <= n; i++) { a[i] = (b[i] > x); } build(1, n, 1); //cout << C[1] << endl; for (int i = 1; i <= q; i++) { int L = LL[i], R = RR[i]; int one = query(L, R, 1, n, 1); //cout << "(" << L << ", " << R << ") one = " << one << endl; int zero = R - L + 1 - one; if (op[i] == 0) { if (zero > 0) update(L, L + zero - 1, 0, 1, n, 1); if (one > 0) update(R - one + 1, R, 1, 1, n, 1); } else { if (one > 0) update(L, L + one - 1, 1, 1, n, 1); if (zero > 0) update(R - zero + 1, R, 0, 1, n, 1); } } return (query(k, k, 1, n, 1) == 0);}void solve(int l, int r) { int res = -1; while (l <= r) { int mid = (l + r) >> 1; int tmp = cal(mid); //cout << mid << " " << tmp << endl; if (tmp) { r = mid - 1; res = mid; } else l = mid + 1; } printf("%d\n", res);}int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &q); for (int i = 1; i <= n; i++) { scanf("%d", &b[i]); } for (int i = 1; i <= q; i++) scanf("%d%d%d", &op[i], &LL[i], &RR[i]); scanf("%d", &k); solve(1, n); } return 0;}
阅读全文
0 0
- HDU 5649 (二分 线段树)
- HDU 5649 线段树+二分
- hdu 4339 线段树+二分
- hdu 4614 线段树+二分~
- HDU 4614 线段树+二分
- HDU 4791二分+线段树
- HDU - 4973(线段树+二分)
- hdu 4339 线段树+二分
- hdu 4614 线段树+二分
- hdu 5592 线段树 + 二分
- HDU 3450 线段树+二分
- hdu 4614 线段树+二分
- HDU 6070 二分+线段树
- hdu 6070二分+线段树
- HDU 4614 线段树+二分
- hdu 5649 DZY Loves Sorting(二分+线段树)
- [HDU 5649] DZY Loves Sorting (线段树+二分)
- HDU 5649 DZY Loves Sorting(线段树+二分)
- 环境变量与文件查找【linux】
- 判断相同的子树--uva12219 Common Subexpression Elimination
- net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM.
- win7基础 cmd 查看字符编码格式
- 遇到枪击事件,你最该做的事儿
- HDU 5649 线段树+二分
- Jzoj3928 射♂击
- C++ 中的 new/delete 和 new[]/delete[]
- windows 安装tensorflow
- web项目优化
- js-es6-Map数据结构
- 假期只是玩就没意思了!告诉你一个学习麻省理工大学所有课程的好地方
- 数据科学家线性规划入门指南
- win7基础 整个屏幕图像的截取 PrntScr键