Luogu 2824 [HEOI2016/TJOI2016]排序
BZOJ 4552
挺妙的解法。
听说这题直接用一个桶能拿到$80 \ pts$
发现如果是一个排列的话,要对这个序列排序并不好做,但是假如是$01$序列的话,要对一个区间排序还是很简单的。
发现最后的询问其实只有一个,所以我们考虑二分这个答案(其实感觉在这题中答案的单调性并不是很明显),每一次二分得到一个$mid$,对于所有的$a_i$,我们把$a_i \geq mid$的$i$都记为$1$,把所有$a_i < mid$的值都记为$0$,然后对于每一次排序,我们只要获取这个区间的$0$和$1$的个数,然后区间覆盖一下就可以了。
区间覆盖,区间求和,岂不是线段树。
这样子所有操作完成了之后,我们只要看一看原来询问的这个位置的数是不是$1$,如果是$1$,那么说明这里的数$\geq mid$,移动左端点,否则移动右端点。
答案的单调性在这个时候就显现出来了。
这个思想值得借鉴。
时间复杂度$O(nlog^2n)$。
Code:
#include <cstdio>
#include <cstring>
using namespace std; const int N = 1e5 + ; int n, m, K, a[N], b[N]; struct Option {
int type, x, y;
} q[N]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > ''|| ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} namespace SegT {
int s[N << ], tag[N << ]; #define lc p << 1
#define rc p << 1 | 1
#define mid ((l + r) >> 1) inline void up(int p) {
if(p) s[p] = s[lc] + s[rc];
} inline void down(int p, int l, int r) {
if(tag[p] == -) return;
s[lc] = tag[p] * (mid - l + ), tag[lc] = tag[p];
s[rc] = tag[p] * (r - mid), tag[rc] = tag[p];
tag[p] = -;
} void build(int p, int l, int r) {
tag[p] = -;
if(l == r) {
s[p] = b[l];
return;
} build(lc, l, mid);
build(rc, mid + , r);
up(p);
} void modify(int p, int l, int r, int x, int y, int v) {
if(x <= l && y >= r) {
s[p] = (r - l + ) * v;
tag[p] = v;
return;
} down(p, l, r);
if(x <= mid) modify(lc, l, mid, x, y, v);
if(y > mid) modify(rc, mid + , r, x, y, v);
up(p);
} int query(int p, int l, int r, int x, int y) {
if(x <= l && y >= r) return s[p]; down(p, l, r); int res = ;
if(x <= mid) res += query(lc, l, mid, x, y);
if(y > mid) res += query(rc, mid + , r, x, y);
return res;
} #undef lc
#undef rc
#undef mid } using namespace SegT; inline bool chk(int mid) {
for(int i = ; i <= n; i++)
if(mid <= a[i]) b[i] = ;
else b[i] = ; build(, , n);
for(int i = ; i <= m; i++) {
int num1 = query(, , n, q[i].x, q[i].y);
int num0 = q[i].y - q[i].x + - num1;
if(!q[i].type) {
if(num0) modify(, , n, q[i].x, q[i].x + num0 - , );
modify(, , n, q[i].x + num0, q[i].y, );
} else {
if(num1) modify(, , n, q[i].x, q[i].x + num1 - , );
modify(, , n, q[i].x + num1, q[i].y, );
}
} int res = query(, , n, K, K);
return (res > );
} int main() {
read(n), read(m);
for(int i = ; i <= n; i++) read(a[i]);
for(int i = ; i <= m; i++)
read(q[i].type), read(q[i].x), read(q[i].y);
read(K); int ln = , rn = n, mid, res;
for(; ln <= rn; ) {
mid = (ln + rn) / ;
if(chk(mid)) ln = mid + , res = mid;
else rn = mid - ;
} printf("%d\n", res);
return ;
}
Luogu 2824 [HEOI2016/TJOI2016]排序的更多相关文章
- [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)
题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...
- 洛谷 2824 [HEOI2016/TJOI2016]排序
[题意概述] 对一个1到n的排列做m次区间排序,最后询问位置q上面的数. [题解] 区间排序的效率是nlogn,所以暴力做的话效率是mnlogn,显然达不到要求. 我们考虑二分答案.如果某个位置的数比 ...
- luogu P2824 [HEOI2016/TJOI2016]排序
题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行 ...
- Luogu P2824 [HEOI2016/TJOI2016]排序 线段树+脑子
只会两个$log$的$qwq$ 我们二分答案:设答案为$ans$,则我们把$a[i]<=ans$全部设成$0$,把$a[i]>ans$全部设成$1$,扔到线段树里,这样区间排序(升序)就是 ...
- 「Luogu P2824 [HEOI2016/TJOI2016]排序」
一道十分神奇的线段树题,做法十分的有趣. 前置芝士 线段树:一个十分基础的数据结构,在这道题中起了至关重要的作用. 一种基于01串的神奇的二分思想:在模拟赛中出现了这道题,可以先去做一下,这样可能有助 ...
- 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)
2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...
- 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告
P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...
- [HEOI2016/TJOI2016]排序 线段树+二分
[HEOI2016/TJOI2016]排序 内存限制:256 MiB 时间限制:6000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而 ...
- [HEOI2016&TJOI2016] 排序(线段树)
4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2703 Solved: 1386[S ...
随机推荐
- 远程激活.NET REFLECTOR(不能断网)
由于是远程连接的服务器,使用.Net Reflector注册机激活时,不能断网. 如何禁止Reflector连接她的激活服务器,可进行如下操作: 1.添加hosts: 0.0.0.0 red-gate ...
- LeetCode Reverse String II
原题链接在这里:https://leetcode.com/problems/reverse-string-ii/#/description 题目: Given a string and an inte ...
- 如何用nodejs启一个前端服务
1.新建文件夹,如 notice 2.新建页面和js文件,如 index.html server.js 3.index.html页面内容随你写,如: <!DOCTYPE html> < ...
- 【转】Cron表达式简介
Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: Seconds Minutes Hours DayofMonth Month ...
- SQL Sever 学习系列之三
SQL Sever 学习系列之三 SQL Server 学习系列之一(薪酬方案+基础) SQL Server 学习系列之二(日期格式问题) 五.经理今天刚谈到with的用法(with的 ...
- C/C++变量命名规则,个人习惯总结【转载】
C_C++变量命名规则 原文地址:http://blog.sina.com.cn/s/blog_8a7012cf01017h9p.html 变量命名规则是为了增强代码的可读性和容易维护性.以下为C++ ...
- h5 离线缓存小demo
传统的web应用是在线应用,这其实也是web的特色,对于PC时代问题并不大,但到了移动互联网时代,设备终端位置不再固定,依赖无线信号,网络的可靠性变得更低.比如:在火车上,穿山越岭进隧道,便无法访问w ...
- PHP怎么把经过UTF-8编码的中文字符转换成正常的中文
问题的场景: html 为utf-8编码<meta http-equiv="Content-Type" content="text/html; charset=UT ...
- sntp协议简介
SNTP(Simple Network Time Protocal简单网络时间协议),用于跨广域网或局域网同步时间的协议,具有较高的精确度(几十毫秒).SNTP是NTP协议的简化版,两者分别在RFC1 ...
- (转)NHibernate各种数据库配置写法
本文转载自:http://blog.csdn.net/hsg77/article/details/23463733 //NHibernate各种数据库连接参数文件配置方法说明 //配置文件Config ...