嘟嘟嘟




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

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




根据做题经验,我想到了给这个序列转化成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. python使用tcp实现一个简单的下载器

    上一篇中介绍了tcp的流程,本篇通过写一个简单的文件下载器程序来巩固之前学的知识. 文件下载器的流程如下: 客户端: 输入目标服务器的ip和port 输入要下载文件的名称 从服务器下载文件保存到本地 ...

  2. confidence interval

    95%置信区间.置信区间的两端被称为置信极限.对一个给定情形的估计来说,置信水平越高,所对应的置信区间就会越大. 对置信区间的计算通常要求对估计过程的假设(因此属于参数统计),比如说假设估计的误差是成 ...

  3. vue(四)-vuex与组件联合使用

    官方定义: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.我的理解就是,vuex就是前端的数据库. 1.首先核心是store,是个仓库,包含着state,因此第一步需要新建一个sto ...

  4. git入门 创建版本库, 版本管理 分支 标签

    参考: https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 GIT最流行的分布式版本 ...

  5. 构造方法为private与类修饰符为final

    构造方法为private的:在这个类外1:不能继承这个类2:不能用new来产生这个类的实例 在这个类内:1:可以继承这个类2:可以用new来产生这个类的实例 类修饰符为final的:在这个类外1:不能 ...

  6. C#DataTable复制、C#DataTable列复制、C#DataTable字段复制

    try { //获取满足条件的数据 DataTable Mdr = datable.Select().ToString("yyyy-MM-dd HH:mm:ss") + " ...

  7. blfs(systemd版本)学习笔记-构建ibus-libpinyin使用中文输入法

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 一.包的下载地址 1.libpinyin 下载地址:http://deb.debian.org/debian/pool/main ...

  8. 用js实现超链接导航菜单点击切换选中时的状态

    项目中使用到点解导航切换不同的颜色,如果只是li选项卡还好办,这次用到的超链接选项卡,因为a链接每次点击都会刷新,所以浏览器记不住点击的状态,也没法切换点击状态,因为项目中有好多地方要用到,在网上找了 ...

  9. 深入理解Java虚拟机05--虚拟机类加载机制

    一.前言 我们一定心里有个疑问,我们那个多态是怎么回事?我们指定的一个接口,却可以等到运行时可以对应于不同的实现类.这是因为,Java有个特性就是依赖运行期动态加载和动态连接,这样实现了Java可以动 ...

  10. spring Boot 出现:org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.

    org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplication ...