要点

  • 序列是n个不同的数,则新学到的一种策略就是二分这个位置的答案,然后可以上下调。
  • 神奇地只关注大于还是小于mid并赋值0、1,这样m个操作的排序就能用线段树维护了!
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn = 1e5 + 5;
int n, m, a[maxn], op[maxn], L[maxn], R[maxn], question; class SegmentTree {
public:
#define ls(p) p << 1
#define rs(p) p << 1 | 1 struct Node {
int l, r, sum, tag;
}t[maxn * 3]; void Push_up(int p) {
t[p].sum = t[ls(p)].sum + t[rs(p)].sum;
} void Change(int son, int fa) {
t[son].tag = t[fa].tag;
t[son].sum = t[fa].tag * (t[son].r - t[son].l + 1);
} void Push_down(int p) {
if (t[p].tag < 0) return;
Change(ls(p), p), Change(rs(p), p);
t[p].tag = -1;
} void Build(int l, int r, int p, int val) {
t[p].l = l, t[p].r = r, t[p].tag = -1;
if (l == r) {
t[p].sum = a[l] >= val;
return;
}
int mid = (l + r) >> 1;
Build(l, mid, ls(p), val);
Build(mid + 1, r, rs(p), val);
Push_up(p);
} void Modify(int l, int r, int p, int k) {
if (l <= t[p].l && t[p].r <= r) {
t[p].tag = k;
t[p].sum = k * (t[p].r - t[p].l + 1);
return;
}
Push_down(p);
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) Modify(l, r, ls(p), k);
if (mid < r) Modify(l, r, rs(p), k);
Push_up(p);
} int Query(int l, int r, int p) {
if (l <= t[p].l && t[p].r <= r) return t[p].sum;
Push_down(p);
int mid = (t[p].l + t[p].r) >> 1;
if (l > mid) return Query(l, r, rs(p));
if (r <= mid) return Query(l, r, ls(p));
return Query(l, r, ls(p)) + Query(l, r, rs(p));
}
}; bool OK(int mid) {
SegmentTree tree;
tree.Build(1, n, 1, mid);
for (int i = 1; i <= m; i++) {
int val = tree.Query(L[i], R[i], 1);
if (val == 0 || val == R[i] - L[i] + 1) continue;
if (op[i]) {
tree.Modify(L[i], L[i] + val - 1, 1, 1);
tree.Modify(L[i] + val, R[i], 1, 0);
} else {
tree.Modify(R[i] - val + 1, R[i], 1, 1);
tree.Modify(L[i], R[i] - val, 1, 0);
}
}
return tree.Query(question, question, 1) == 1;
} int main() {
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], &L[i], &R[i]);
scanf("%d", &question); int l = 1, r = n, ans;
while (l <= r) {
int mid = (l + r) >> 1;
if (OK(mid)) ans = mid, l = mid + 1;
else r = mid - 1;
} return !printf("%d\n", ans);
}

BZOJ4552(二分+线段树)的更多相关文章

  1. HDU4614 Vases and Flowers 二分+线段树

    分析:感觉一看就是二分+线段树,没啥好想的,唯一注意,当开始摆花时,注意和最多能放的比大小 #include<iostream> #include<cmath> #includ ...

  2. J - Joseph and Tests Gym - 102020J (二分+线段树)

    题目链接:https://cn.vjudge.net/contest/283920#problem/J 题目大意:首先给你n个门的高度,然后q次询问,每一次询问包括两种操作,第一种操作是将当前的门的高 ...

  3. Educational Codeforces Round 61 D 二分 + 线段树

    https://codeforces.com/contest/1132/problem/D 二分 + 线段树(弃用结构体型线段树) 题意 有n台电脑,只有一个充电器,每台电脑一开始有a[i]电量,每秒 ...

  4. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

  5. hdu6070 Dirt Ratio 二分+线段树

    /** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...

  6. K-th occurrence HDU - 6704 (后缀数组+二分线段树+主席树)

    大意: 给定串s, q个询问(l,r,k), 求子串s[l,r]的第kk次出现位置. 这是一篇很好的题解: https://blog.csdn.net/sdauguanweihong/article/ ...

  7. BZOJ4552 [Tjoi2016&Heoi2016]排序 【二分 + 线段树】

    题目链接 BZOJ4552 题解 之前去雅礼培训做过一道题,\(O(nlogn)\)维护区间排序并能在线查询 可惜我至今不能get 但这道题有着\(O(nlog^2n)\)的离线算法 我们看到询问只有 ...

  8. [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树

    Brief Description DZY有一个数列a[1..n],它是1∼n这n个正整数的一个排列. 现在他想支持两种操作: 0, l, r: 将a[l..r]原地升序排序. 1, l, r: 将a ...

  9. 2018.08.01 BZOJ4552: [Tjoi2016&Heoi2016]排序(二分+线段树)

    传送门 线段树简单题. 二分答案+线段树排序. 实际上就是二分答案mid" role="presentation" style="position: relat ...

  10. BZOJ4552 Tjoi2016&Heoi2016排序 【二分+线段树】*

    Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这个 ...

随机推荐

  1. BZOJ2809:[APIO2012]dispatching

    浅谈左偏树:https://www.cnblogs.com/AKMer/p/10246635.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php? ...

  2. IIC编程1:i2c-tools使用

    安装: apt-get install libi2c-dev i2c-tools 检测i2c总线数目 用i2cdetect检测有几组i2c总线在系统上: i2cdetect -l 可以看到系统中有9组 ...

  3. 2008上交:Day of Week

    题目描述: We now use the Gregorian style of dating in Russia. The leap years are years with number divis ...

  4. ZOJ1610(经典线段树涂色问题)

    Description Painting some colored segments on a line, some previously painted segments may be covere ...

  5. RabbitMQ队列,Redis\Memcached缓存

    RabbitMQ RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统. MQ全称Message Queue,消息队列(MQ)是一种应用程序对应用程序的通信方式.应用程序通过读写出入队列 ...

  6. Mysql 数据库时间更新字段

    关于时间更新: 创建时间: CURRENT_TIMESTAMP 更新时间: 勾选根据时间戳更新

  7. [bzoj2038]莫队算法学习

    解题关键:莫队最重要的是区间之间以$O(1)$的复杂度进行转化,由于电脑原因,后续补上公式推导. #include<cstdio> #include<cstring> #inc ...

  8. Hadoop YARN配置参数剖析(3)—MapReduce相关参数

    MapReduce相关配置参数分为两部分,分别是JobHistory Server和应用程序参数,Job History可运行在一个独立节点上,而应用程序参数则可存放在mapred-site.xml中 ...

  9. 通过sessionid提取这个用户在服务器中保存的session变量

  10. Linux 启动顺序

    Linux 启动顺序:1. BIOS自检2. 运行系统内核并检测硬件3. 运行系统的第一个进程init4. init读取系统引导配置文件/etc/inittab中的信息进行初始化            ...