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 ...
随机推荐
- Android Volley完全解析(二),使用Volley加载网络图片
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17482165 在上一篇文章中,我们了解了Volley到底是什么,以及它的基本用法. ...
- CANopenNode drvTemplate/CO_driver.h hacking
/************************************************************************ * CANopenNode drvTemplate/ ...
- 洛谷P2706 巧克力
题目背景 王7的生日到了,他的弟弟准备送他巧克力. 题目描述 有一个被分成n*m格的巧克力盒,在(i,j)的位置上有a[i,j]块巧克力.就在送出它的前一天晚上,有老鼠夜袭巧克力盒,某些位置上被洗劫并 ...
- 【LeetCode】001. TwoSum
题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...
- C++对C语言的拓展(4)—— 函数重载
函数重载(Function Overload):用同一个函数名定义不同的函数,当函数名和不同的参数搭配时函数的含义不同. 1.重载规则 (1)函数名相同: (2)参数个数不同,参数的类型不同,参数顺序 ...
- JavaScript实现继承的几种重要范式
一 原型链 1. 代码示例 function SuperType() { this.superProperty = true; } SuperType.prototype.getSuperValue ...
- 感知机学习算法Java实现
感知机学习算法Java实现. Perceptron类用于实现感知机, 其中的perceptronOriginal()方法用于实现感知机学习算法的原始形式: perceptronAnother()方法用 ...
- Linux应用函数 -- 字符串
1.strchr 原型 char *strchr(const char* _Str,char _Val) 头文件 string.h 功能 查找字符串_Str中首次出现字符_Val的位置 返回值 成功 ...
- 遍历js的obj中所有属性得key
var obj = $("#jstree_default").jstree("get_checked"); for (var a in obj) { alert ...
- Oracle 文件
参数文件 跟踪文件 告警文件 数据文件 临时文件 控制文件 重做日志文件 密码文件 闪回日志 dum文件 数据泵文件 1参数文件 Parameter file:告诉oracle实例在那里可以找到控制文 ...