【BZOJ4552】【HEOI2016】排序 [二分答案][线段树]
排序
Time Limit: 60 Sec Memory Limit: 256 MB
[Submit][Status][Discuss]
Description
Input
Output
输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第q位置上的数字。
Sample Input
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
Sample Output
HINT
1 <= n <= 10^5,1 <= m <= 10^5, 1 <= q <= n。
Solution
我们先考虑如果权值很小的话怎么做,显然可以对每个权值开一个线段树维护在哪些位置出现过。
那么排序显然就是覆盖连续的一段。只要知道某一区间有几个这个权值即可。
但是这样显然是过不了的,于是我们考虑二分答案,把val >= mid的设为1,其余的设为0。
这样就把权值变成了0/1,那么显然我们按照以上操作,如果Q位置上是1说明mid<=Ans,还可以更大一点,否则说明mid>Ans。
只要支持区间求和以及区间覆盖0/1即可。
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE = ;
const int MOD = 1e9 + ; int get()
{
int res = , Q = ; char c;
while( (c = getchar()) < || c > )
if(c == '-') Q = -;
if(Q) res = c - ;
while( (c = getchar()) >= && c <= )
res = res * + c - ;
return res * Q;
} int n, m, Q;
int a[ONE];
int res, now; struct power
{
struct point
{
int val, tag;
}Node[ONE]; void Build(int i, int l, int r)
{
Node[i].tag = -;
if(l == r) return;
int mid = l + r >> ;
Build(i << , l, mid);
Build(i << | , mid + , r);
} int pushdown(int i, int l, int r)
{
int mid = l + r >> ;
if(Node[i].tag != -)
{
Node[i << ].tag = Node[i].tag;
Node[i << ].val = Node[i].tag * (mid - l + );
Node[i << | ].tag = Node[i].tag;
Node[i << | ].val = Node[i].tag * (r - (mid + ) + );
Node[i].tag = -;
}
} void Update(int i, int l, int r, int L, int R, int x)
{
if(L > R) return;
if(L <= l && r <= R)
{
Node[i].tag = x;
Node[i].val = x * (r - l + );
return;
}
pushdown(i, l, r);
int mid = l + r >> ;
if(L <= mid) Update(i << , l, mid, L, R, x);
if(mid + <= R) Update(i << | , mid + , r, L, R, x);
Node[i].val = Node[i << ].val + Node[i << | ].val;
} void Query(int i, int l, int r, int L, int R)
{
if(L > R) return;
if(L <= l && r <= R)
{
res += Node[i].val;
return;
}
pushdown(i, l, r);
int mid = l + r >> ;
if(L <= mid) Query(i << , l, mid, L, R);
if(mid + <= R) Query(i << | , mid + , r, L, R);
}
}C[]; struct operate
{
int l, r, x;
}oper[ONE]; void Modify(int id, int Left, int Right)
{
res = ;
C[id].Query(, , n, Left, Right);
C[id].Update(, , n, Left, Right, );
C[id].Update(, , n, now, now + res - , );
now += res;
} int Check(int mid)
{
for(int i = ; i <= ; i++)
C[i].Node[].tag = ; for(int i = ; i <= n; i++)
C[a[i] >= mid].Update(, , n, i, i, ); for(int i = ; i <= m; i++)
{
now = oper[i].l;
if(oper[i].x == ) for(int id = ; id <= ; id++) Modify(id, oper[i].l, oper[i].r);
if(oper[i].x == ) for(int id = ; id >= ; id--) Modify(id, oper[i].l, oper[i].r);
} res = , C[].Query(, , n, Q, Q);
return res;
} int main()
{
n = get(); m = get();
for(int i = ; i <= n; i++)
a[i] = get();
for(int i = ; i <= m; i++)
oper[i].x = get(), oper[i].l = get(), oper[i].r = get(); Q = get();
int l = , r = n;
while(l < r - )
{
int mid = l + r >> ;
if(Check(mid)) l = mid;
else r = mid;
} if(Check(r)) printf("%d", r);
else printf("%d", l);
}
【BZOJ4552】【HEOI2016】排序 [二分答案][线段树]的更多相关文章
- [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)
解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...
- bzoj 4552 [Tjoi2016&Heoi2016]排序 (二分答案 线段树)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 题意: 给你一个1-n的全排列,m次操作,操作由两种:1.将[l,r]升序排序,2 ...
- BZOJ 4552 [Tjoi2016&Heoi2016]排序 | 二分答案 线段树
题目链接 题面 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- HDU 5649 DZY Loves Sorting(二分答案+线段树/线段树合并+线段树分割)
题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \le ...
- [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)
二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可 然后询问第q个位置的值,为1说明>=mid,以上 时间复杂度O(nlog2 ...
- [HEOI2016/TJOI2016] 排序 解题报告(二分答案/线段树分裂合并+set)
题目链接: https://www.luogu.org/problemnew/show/P2824 题目描述: 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在 ...
- 【Luogu】P2824排序(二分答案+线段树排序)
题目链接 震惊!两个线段树和一个线段树竟是50分的差距! 本题可以使用二分答案,二分那个位置上最后是什么数.怎么验证呢? 把原序列改变,大于等于mid的全部变成1,小于mid的全部变成0,之后线段树排 ...
- bzoj 4552 [Tjoi2016&Heoi2016]排序——二分答案
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案,把 >= mid 的设成1.< mid 的设成0,之后排序就变成 ...
- YbtOJ#463-序列划分【二分答案,线段树,dp】
正题 题目链接:https://www.ybtoj.com.cn/problem/463 题目大意 给出长度为\(n\)的序列\(A,B\).要求划分成若干段满足 对于任何\(i<j\),若\( ...
随机推荐
- C++ Primer Plus学习:第十三章
第十三章 类继承 继承的基本概念 类继承是指从已有的类派生出新的类.例: 表 0-1 player.h class player { private: string firstname; string ...
- mac python install zlib not available
用brew install 3.4.4(python)时报 zipimport.ZipImportError: can't decompress data; zlib not available 的错 ...
- Win10 版本情况 201810
- [Oracle收费标准]
http://www.oracle.com/us/corporate/pricing/technology-price-list-070617.pdf 1: 数据库 2. 中间件 3. weblogi ...
- Kafka在大型应用中的 20 项最佳实践
原标题:Kafka如何做到1秒处理1500万条消息? Apache Kafka 是一款流行的分布式数据流平台,它已经广泛地被诸如 New Relic(数据智能平台).Uber.Square(移动支付公 ...
- 题解 P1469 【找筷子】
这题真是水 咳咳.. 基本思路:桶排 但是可以剪枝. 剪枝方法: 好几种,可以用set(集合),可以用stack(栈), 也可以像我一样的蒟蒻最大最小值...... 但是作者的毒瘤数据应该不会放过我们 ...
- [BZOJ3507]通配符匹配
3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec Memory Limit: 128 MB Description 几乎所有操作系统的命令行界面(CLI)中都支持文件 ...
- 【BZOJ3162】独钓寒江雪(树哈希,动态规划)
[BZOJ3162]独钓寒江雪(树哈希,动态规划) 题面 BZOJ 题解 忽然翻到这道题目,突然发现就是前几天一道考试题目... 题解: 树哈希,既然只考虑这一棵树,那么,如果两个点为根是同构的, 他 ...
- 【BZOJ4129】Haruna’s Breakfast(树上莫队)
[BZOJ4129]Haruna's Breakfast(树上莫队) 题面 BZOJ Description Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了 ...
- Linux内核分析第三周学习博客——跟踪分析Linux内核的启动过程
Linux内核分析第三周学习博客--跟踪分析Linux内核的启动过程 实验过程截图: 过程分析: 在Linux内核的启动过程中,一共经历了start_kernel,rest_init,kernel_t ...