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 ...
随机推荐
- Nhibernate系列学习之(三) Criteria查询表达式增删改查
Criteria查询表达式: 正如我们所见,Expression对查询语句的表达式进行了封装和限制,下表列出了Expression所有的方法,以及每个方法所对应的查询表达式及其限制. Restrict ...
- hdoj-2141-Can you find it?(二分查找)
题目链接 /* Name:HDU-2141-Can you find it? Copyright: Author: Date: 2018/4/12 17:15:46 Description: 暴力,复 ...
- (转)libcurl库使用方法,好长,好详细。
一.ibcurl作为是一个多协议的便于客户端使用的URL传输库,基于C语言,提供C语言的API接口,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP ...
- 【SQL查询】查询结果分组_Group
1. 概述 “Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组 示例 2. group by的简单操作 3. Group By中Select指定的字段限制 select指定的 ...
- 数据处理之pandas库
1. Series对象 由于series对象很简单,跟数组类似,但多了一些额外的功能,偷个懒,用思维导图表示 2. DaraFrame对象 DataFrame将Series的使用场景由一维扩展到多维, ...
- sklearn_算法选择
- 滑雪(经典DP思想)
个人心得:思想还是不够,开始自己写但是不知道如何记录长度,也不太知道状态的转移,后面看了百度, 发现人人为我我为人人就是一步一步推导, 而递归思想就要求学会记录和找到边界条件,这一题中的话就是用递归, ...
- 基于JQ的简单左右轮播图
// 轮播图 主要实现思想: a.第一层div,设置overflow为hidden. b.里面是一个ul,每个li里面有个img或者为每个li设置背景图片也可以. c.li设置为左浮动,排成一行,还有 ...
- vue.js初学(三)模板语法
1:介绍 vue.js允许开发者声明式地将Dom元素绑定至Vue实例的底层,所有的模板都是合法的html,所以能够被遵循规范的浏览器和html解析器解析 在底层的实现上,vue将模板编译成虚拟Dom渲 ...
- bzoj 1951 [Sdoi2010]古代猪文 ——数学综合
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1951 数学综合题. 费马小定理得指数可以%999911658,又发现这个数可以质因数分解.所 ...