HDU 5649 (二分 线段树)
来源:互联网 发布:tvp动画软件 编辑:程序博客网 时间:2024/06/06 02:44
题目链接:点击这里
题意:给出一个排列,每次操作[l,r]区间的数原地升序或者降序,询问最后k下标的数。
二分最后的结果mid,然后把比mid大的换成1,小于等于mid的换成0,那么升序降序相当于求出区间中0的个数然后把前半段和后半段分别用0\1覆盖。这样只需要维护一个区间查询,区间修改的线段树即可。
#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <vector>using namespace std;#define pl c<<1#define pr (c<<1)|1#define lson tree[c].l,tree[c].mid,pl#define rson tree[c].mid+1,tree[c].r,pr#define maxn 100005struct node { int l, r, mid; bool zero, one;///全0全1标记 int num;///0个数}tree[maxn<<3];int op[maxn][3];int a[maxn], b[maxn];int n, m, k;void build_tree (int l, int r, int c) { tree[c].l = l, tree[c].r = r, tree[c].mid = (l+r)>>1; tree[c].zero = tree[c].one = 0; if (l == r) { tree[c].num = (b[l] == 0); return ; } build_tree (lson); build_tree (rson); tree[c].num = tree[pl].num + tree[pr].num;}void push_down (int c) { if (tree[c].l == tree[c].r) return ; if (tree[c].zero) { tree[pl].zero = tree[pr].zero = 1; tree[pl].one = tree[pr].one = 0; tree[pl].num = tree[pl].r-tree[pl].l+1; tree[pr].num = tree[pr].r-tree[pr].l+1; } else if (tree[c].one) { tree[pl].zero = tree[pr].zero = 0; tree[pl].one = tree[pr].one = 1; tree[pl].num = tree[pr].num = 0; }}void update (int l, int r, int c, int x, int y, int op) { if (x > y) return ; push_down (c); if (x == l && y == r) { if (op == 0) { tree[c].zero = 1; tree[c].one = 0; tree[c].num = r-l+1; } else { tree[c].zero = 0; tree[c].one = 1; tree[c].num = 0; } return ; } if (tree[c].mid >= y) update (lson, x, y, op); else if (tree[c].mid < x) update (rson, x, y, op); else { update (lson, x, tree[c].mid, op); update (rson, tree[c].mid+1, y, op); } tree[c].num = tree[pl].num+tree[pr].num; tree[c].zero = tree[c].one = 0;}int query (int l, int r, int c, int x, int y) { push_down (c); if (l == x && y == r) { return tree[c].num; } if (tree[c].mid >= y) { return query (lson, x, y); } else if (tree[c].mid < x) { return query (rson, x, y); } else { return query (lson, x, tree[c].mid)+query (rson, tree[c].mid+1, y); }}bool ok (int x) { for (int i = 1; i <= n; i++) b[i] = (a[i]>x); build_tree (1, n, 1); for (int i = 1; i <= m; i++) { //cout << i << endl; int tot1 = query (1, n, 1, op[i][1], op[i][2]);//0的数量 int tot2 = op[i][2]-op[i][1]+1-tot1;//1的数量 if (op[i][0] == 1) { update (1, n, 1, op[i][1], op[i][1]+tot2-1, 1); update (1, n, 1, op[i][2]-tot1+1, op[i][2], 0); } else { update (1, n, 1, op[i][1], op[i][1]+tot1-1, 0); update (1, n, 1, op[i][2]-tot2+1, op[i][2], 1); } } int res = query (1, n, 1, k, k); return res^1;}int main () { //freopen ("more.in", "r", stdin); int t; scanf ("%d", &t); while (t--) { scanf ("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf ("%d", &a[i]); for (int i = 1; i <= m; i++) scanf ("%d%d%d", &op[i][0], &op[i][1], &op[i][2]); scanf ("%d", &k); int l = 1, r = n; while (r-l > 1) { int mid = (l+r)>>1; if (ok (mid)) l = mid; else r = mid; } printf ("%d\n", ok (l) ? r : l); } 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(线段树+二分)
- 浏览器是如何实现事件——事件的源头EventTarget
- 用变量a给出下面的定义
- 关于include的正确理解和用法
- mybatis的查询类型
- Red Hat Enterprise 6.5 在虚拟机上将系统语言修改为中文
- HDU 5649 (二分 线段树)
- 关于 ZJCPC2004第二题
- Java VisualVM 多线程监控分析工具
- autoload之composer分析
- 我的第一次vi经历
- 详解Java中native关键字
- HDU 1711 Number Sequence【数字KMP】
- 统一会话
- php单例模式