【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\),若\( ...
随机推荐
- 对IT行业的一些思考
阅读完两篇报道,从“2014年十大最热门行业和职业排行榜”可以看出最热门的行业是IT行业,可以看出IT行业在未来的发展前景很乐观,选择IT行业的人也会越来越多,IT行业也会越来越庞大.但是 ...
- Beta阶段冲刺第一天
提供当天站立式会议照片一张 讨论项目每个成员的昨天进展 昨天开始了Beta阶段的冲刺,总体讨论了一下这个阶段的任务,然后明确了个人分工. 讨论项目每个成员的存在问题 第一天暂时还没有什么问题,可能最大 ...
- 微信小程序 功能函数 touch触摸计时
shiFN:function(e){ // touchstart // touchend let that=this; let n=0; // 判断是开始还是结束的参数 let textTure = ...
- 我的系统资源呢?php-fpm你知道吗?
1:别的先不管咱们top一下.看看咱们的cpu ram swap的使用情况 由上图分析,可以看出共有602个进程,其中有601个进程休眠了.这好像有点不对劲,内核进程也就80个左右,加上memcach ...
- 记一次Spring配置事故
在引入Spring的Validated时,需要声明如下bean: @Beanpublic MethodValidationPostProcessor methodValidationPostPro ...
- [乱搞]hdu 6406 Taotao picks apples 笛卡尔树+倍增
题目链接 Problem Description There is an apple tree in front of Taotao's house. When autumn comes, n app ...
- 【MediaElement】WPF视频播放器【3】
一.前言 对于<MediaElement>前两章介绍了差不多了,其实好的界面还需要UI工程师的配合,比如帮忙设计下按钮的样式等等.同样视频本身也需要吸引人,不然做的再好的播放器也没用.之后 ...
- 【bzoj4869】相逢是问候
Portal-->bzoj4869 Solution 这道题的话..长得就是线段树的样子qwq 如果做过的话..可能会联想到bzoj3211(没写博qwq晚点再说吧哈哈..) 首先大胆猜一波结论 ...
- fork系统炸弹
最近偶然看到"fork系统炸弹"的代码,小小一行shell竟然能够直接搞死系统,令人印象深刻. 代码如下 :(){ :|:& };: 咋一看有点蒙,重新排版下格式 :() ...
- mysql命令修改登录用户密码
方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password(‘新密码’); 例子:my ...