嘟嘟嘟




首先这题的暴力是十分好写的,而且据说能得不少分。

正解写起来不难,就是不太好想。




根据做题经验,我想到了给这个序列转化成01序列,但是接下来我就不会了。还是看了题解。

因为查询只有一个数,所以可以二分答案:把大于等于mid的数标记成1,小于mid的数为0.这样排序就是区间赋值了,线段树可做。

那怎么检验mid是否正确呢?其实这个是有单调性的:如果二分的是1,那么很显然最后位置\(q\)上一定是1,随着二分的值变大,位置\(q\)上是1的可能性就越小。这大抵就是二分的单调性?

(这只能算是感性理解吧)

或者说如果第\(Q\)位是1,那么答案就是\([mid, R]\),否则就是\([L, mid - 1]\)。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int n, m, Q, a[maxn];
bool b[maxn];
struct Node
{
int op, L, R;
}q[maxn]; int l[maxn << 2], r[maxn << 2], sum[maxn << 2], lzy[maxn << 2];
In void build(int L, int R, int now)
{
l[now] = L, r[now] = R;
lzy[now] = -1;
if(L == R) {sum[now] = b[L]; return;}
int mid = (L + R) >> 1;
build(L, mid, now << 1);
build(mid + 1, R, now << 1 | 1);
sum[now] = sum[now << 1] + sum[now << 1 | 1];
}
In void change(int now, int flg)
{
sum[now] = (r[now] - l[now] + 1) * flg;
lzy[now] = flg;
}
In void pushdown(int now)
{
if(~lzy[now])
{
change(now << 1, lzy[now]), change(now << 1 | 1, lzy[now]);
lzy[now] = -1;
}
}
In void update(int L, int R, int now, int flg)
{
if(L > R) return;
if(l[now] == L && r[now] == R) {change(now, flg); return;}
pushdown(now);
int mid = (l[now] + r[now]) >> 1;
if(R <= mid) update(L, R, now << 1, flg);
else if(L > mid) update(L, R, now << 1 | 1, flg);
else update(L, mid, now << 1, flg), update(mid + 1, R, now << 1 | 1, flg);
sum[now] = sum[now << 1] + sum[now << 1 | 1];
}
In int query(int L, int R, int now)
{
if(l[now] == L && r[now] == R) return sum[now];
pushdown(now);
int mid = (l[now] + r[now]) >> 1;
if(R <= mid) return query(L, R, now << 1);
else if(L > mid) return query(L, R, now << 1 | 1);
else return query(L, mid, now << 1) + query(mid + 1, R, now << 1 | 1);
} In bool judge(int x)
{
for(int i = 1; i <= n; ++i) b[i] = (a[i] >= x);
build(1, n, 1);
for(int i = 1; i <= m; ++i)
{
int tp = query(q[i].L, q[i].R, 1);
if(!q[i].op)
{
update(q[i].L, q[i].R - tp, 1, 0);
update(q[i].R - tp + 1, q[i].R, 1, 1);
}
else
{
update(q[i].L, q[i].L + tp - 1, 1, 1);
update(q[i].L + tp, q[i].R, 1, 0);
}
}
return query(Q, Q, 1);
} int main()
{
n = read(), m = read();
for(int i = 1; i <= n; ++i) a[i] = read();
for(int i = 1; i <= m; ++i) q[i].op = read(), q[i].L = read(), q[i].R = read();
Q = read();
int L = 1, R = n;
while(L < R)
{
int mid = (L + R + 1) >> 1;
if(judge(mid)) L = mid;
else R = mid - 1;
}
write(L), enter;
return 0;
}

[HEOI2016/TJOI2016]排序的更多相关文章

  1. 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告

    P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...

  2. [HEOI2016/TJOI2016]排序 线段树+二分

    [HEOI2016/TJOI2016]排序 内存限制:256 MiB 时间限制:6000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而 ...

  3. [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)

    题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...

  4. 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)

    2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...

  5. [HEOI2016&TJOI2016] 排序(线段树)

    4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2703  Solved: 1386[S ...

  6. 【线段树合并】【P2824】 [HEOI2016/TJOI2016]排序

    Description 给定一个长度为 \(n\) 的排列,有 \(m\) 次操作,每次选取一段局部进行升序或降序排序,问你一波操作后某个位置上的数字是几 Hint \(1~\leq~n,~m~\le ...

  7. 【[HEOI2016/TJOI2016]排序】

    巧妙思路题 有一个重要的思想就是把大于某一个数的数都变成\(1\),小于这个数的都变成\(0\),这个只有\(0\)和\(1\)的序列就很好处理了 由于我们只需要在最后求出一个位置上是什么数就可以了, ...

  8. BZOJ4552:[HEOI2016/TJOI2016]排序——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4552 https://www.luogu.org/problemnew/show/P2824 在2 ...

  9. [洛谷P2824][HEOI2016/TJOI2016]排序

    题目大意:一个全排列,两种操作: 1. $0\;l\;r:$把$[l,r]$升序排序2. $1\;l\;r:$把$[l,r]$降序排序 最后询问第$k$位是什么 题解:二分答案,把比这个数大的赋成$1 ...

随机推荐

  1. Java学习笔记之——构造方法

    构造方法:方法名和类名相同且没有返回值 1.作用 创建对象 对象初始化 2.普通方法的结构 权限修饰符 返回值类型 方法名(形参){ 方法体: } 3. 构造方法的结构 (1)结构 权限修饰符 方法名 ...

  2. Linux上Simplescalar/ARM的安装和运行文档

    本文是基于ARM的simplescalar在ubuntu下的安装说明 1.1 软件下载  *********************文件下载地址:http://yunpan.cn/cw2n7dAyfG ...

  3. file上传图片,base64转换、压缩图片、预览图片、将图片旋转到正确的角度

    /** * 将base64转换为文件对象 * (即用文件上传输入框上传文件得到的对象) * @param {String} base64 base64字符串 */ function convertBa ...

  4. 30.Odoo产品分析 (四) – 工具板块(2) – 搜索和仪表盘(2)

    查看Odoo产品分析系列--目录 在前面的模块中,简单介绍过了odoo如何搜索系统中的各种数据集,并保存这些过滤器,以便在之后需要时能够轻松访问这些过滤器.这里将做更详细的介绍.最后分析仪表盘的功能, ...

  5. 我喜欢 Google Flutter

    在 Google I/O ’17 上,Google 向我们介绍了 Flutter —— 一款新的用于创建移动应用的开源库. 正如你所想的那样,Flutter 是能够帮助创建拥有漂亮 UI 界面的跨平台 ...

  6. winsock 编程(简单客户&服务端通信实现)

    winsock 编程(简单客户&服务端通信实现) 双向通信:Client send message to Server, and if  Server receive the message, ...

  7. spring学习总结——装配Bean学习一(自动装配)

    一.Spring配置的可选方案 Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系.但是,作为开发人员,你需要告诉Spring要创建哪些bean并且如何将其装配在一起.当描 ...

  8. 【软件需求工程与建模 - 小组项目】第6周 - 成果展示3 - 软件设计规格说明书V4.1

    成果展示3 - 软件设计规格说明书V4.1

  9. 2019年Web前端入门的自学路线

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文.本文内容不定期更新. 我前几天写过一篇文章:<裸辞两个月,海投一个月 ...

  10. 如何实现javascript js 类命名空间的写法

    转载 猫猫小屋http://www.maomao365.com/?p=823 在C#中有namespace概念,java中有package的概念,有了这些概念之后,在系统的运行时,每一个方法就会拥有唯 ...