bzoj4552: [Tjoi2016&Heoi2016]排序(二分+线段树)
又是久违的1A哇...
好喵喵的题!二分a[p],把大于mid的数改为1,小于等于mid的数改为0,变成01串后就可以用线段树进行那一连串排序了,排序后如果p的位置上的数为0,说明答案比mid小,如果为1,说明答案比mid大。
如何理解呢?我们的目的其实是让比a[p]大的数都为1,这样子p位置上刚好为0。如果p位置上为1,说明mid较小,a[p]>mid,把a[p]给标记成了1。如果p位置上为0,就是把a[p]<=mid,把a[p]标记成了0,但是这样还有一些大于a[p]的位置也是0,所以继续往小的地方逼近答案。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=,inf=1e9;
struct poi{int sum,tag;}tree[maxn];
int n,m,q;
int a[maxn],b[maxn],l[maxn],r[maxn],ty[maxn];
inline void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
inline void pushup(int x){tree[x].sum=tree[x<<].sum+tree[x<<|].sum;}
inline void pushdown(int x,int l,int r)
{
if(tree[x].tag==-)return;
int mid=(l+r)>>;
if(tree[x].tag==)
{
tree[x<<].sum=mid-l+;tree[x<<].tag=;
tree[x<<|].sum=r-mid;tree[x<<|].tag=;
}
else tree[x<<].sum=tree[x<<|].sum=tree[x<<].tag=tree[x<<|].tag=;
tree[x].tag=-;
}
void build(int x,int l,int r)
{
tree[x].tag=-;
if(l==r){tree[x].sum=b[l];return;}
int mid=(l+r)>>;
build(x<<,l,mid);build(x<<|,mid+,r);
pushup(x);
}
void update(int x,int l,int r,int cl,int cr,int ty)
{
if(cl<=l&&r<=cr){tree[x].sum=ty*(r-l+);tree[x].tag=ty;return;}
pushdown(x,l,r);
int mid=(l+r)>>;
if(cl<=mid)update(x<<,l,mid,cl,cr,ty);
if(cr>mid)update(x<<|,mid+,r,cl,cr,ty);
pushup(x);
}
int query(int x,int l,int r,int cl,int cr)
{
if(cl<=l&&r<=cr)return tree[x].sum;
pushdown(x,l,r);
int mid=(l+r)>>,ret=;
if(cl<=mid)ret+=query(x<<,l,mid,cl,cr);
if(cr>mid)ret+=query(x<<|,mid+,r,cl,cr);
return ret;
}
bool check(int x)
{
for(int i=;i<=n;i++)b[i]=a[i]>x;
build(,,n);
for(int i=;i<=m;i++)
{
int x=query(,,n,l[i],r[i]);
if(ty[i])
{
if(x)update(,,n,l[i],l[i]+x-,);
if(l[i]+x<=r[i])update(,,n,l[i]+x,r[i],);
}
else
{
if(l[i]<=r[i]-x)update(,,n,l[i],r[i]-x,);
if(x)update(,,n,r[i]-x+,r[i],);
}
}
return !query(,,n,q,q);
}
int main()
{
read(n);read(m);
for(int i=;i<=n;i++)read(a[i]);
for(int i=;i<=m;i++)read(ty[i]),read(l[i]),read(r[i]);
read(q);
int l=,r=n;
while(l<r)
{
int mid=(l+r)>>;
if(check(mid))r=mid;
else l=mid+;
}
printf("%d",l);
}
bzoj4552: [Tjoi2016&Heoi2016]排序(二分+线段树)的更多相关文章
- [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树
Brief Description DZY有一个数列a[1..n],它是1∼n这n个正整数的一个排列. 现在他想支持两种操作: 0, l, r: 将a[l..r]原地升序排序. 1, l, r: 将a ...
- 【BZOJ4552】[Tjoi2016&Heoi2016]排序 二分+线段树
[BZOJ4552][Tjoi2016&Heoi2016]排序 Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ...
- bzoj 4552: [Tjoi2016&Heoi2016]排序——二分+线段树
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)
解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...
- bzoj千题计划128:bzoj4552: [Tjoi2016&Heoi2016]排序
http://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案 把>=mid 的数看做1,<mid 的数看做0 这样升序.降序排列相当于 ...
- BZOJ4552 [Tjoi2016&Heoi2016]排序 【二分 + 线段树】
题目链接 BZOJ4552 题解 之前去雅礼培训做过一道题,\(O(nlogn)\)维护区间排序并能在线查询 可惜我至今不能get 但这道题有着\(O(nlog^2n)\)的离线算法 我们看到询问只有 ...
- BZOJ4552:[TJOI2016&HEOI2016]排序(线段树,二分)
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他. 这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- 2018.08.01 BZOJ4552: [Tjoi2016&Heoi2016]排序(二分+线段树)
传送门 线段树简单题. 二分答案+线段树排序. 实际上就是二分答案mid" role="presentation" style="position: relat ...
- BZOJ4552 Tjoi2016&Heoi2016排序 【二分+线段树】*
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这个 ...
- [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)
二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可 然后询问第q个位置的值,为1说明>=mid,以上 时间复杂度O(nlog2 ...
随机推荐
- 即刻开始使用Kotlin开发Android的12个原因(KAD 30)
作者:Antonio Leiva 时间:Jul, 11, 2017 原文链接:https://antonioleiva.com/reasons-kotlin-android/ 这组文章已到最后了,它们 ...
- wpf基础使用_修改窗体图标
废话不多说,直接开始修改图标步骤: 当然直接使用绝对路径添加图标也是可以的,这种方式不可取,一旦图标移动位置或被删除,就会导致找不到图标文件报错,这里我们介绍的是另一个方式,使用资源文件的方式添加 1 ...
- Unity编辑器 - 资源批处理工具基类
Unity编辑器 - 资源批处理工具基类 经常要对资源进行批处理,很多时候都是一次性的需求,于是弄个通用脚本. 工具是个弹出面板,处理过程有进度条,如下: 如图,子类只需要重写几个方法: using ...
- 树莓派 Raspberry Pi 与 micro:bit起手式
本文将学习如何在Raspberry Pi上安装MicroPython编辑器mu,并将MicroPython中编写的程序从您的Raspberry Pi推送到micro:bit. 您需要: 硬件, 带有S ...
- flume 整合 kafka
flume 整合 kafka: flume:高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统. kafka:分布式的流数据平台. flume 采集业务日志,发送到kafka 一. ...
- VMware SDK使用指南
刚开始用VMware官方推荐的SDK,真的是又臭又长,代码结构不清晰,易读性差.后来VMware的同学给推荐了一款开源的SDK,一上手感觉工作效率提高了100倍!推荐大家使用~. 该SDK对VMwar ...
- Java集合学习--集合总结
一.ArrayList与Vector ArrayList与Vector很多地方大同小异,Vector现在已经基本不再使用.具体的管理如下:1.ArrayList与Vector都实现了List接口,底层 ...
- 小米 OJ 编程比赛 02 月常规赛
Carryon 数数字 描述 Carryon 最近迷上了数数字,然后 Starry 给了他一个区间[l,r] ,然后提了几个要求, 需要将 ll 到 rr 之间的数全部转化成 16 进制,然后连起来. ...
- Paper Reading - CNN+CNN: Convolutional Decoders for Image Captioning
Link of the Paper: https://arxiv.org/abs/1805.09019 Innovations: The authors propose a CNN + CNN fra ...
- How Does Batch Normalization Help Optimization?
1. 摘要 BN 是一个广泛应用的用于快速稳定地训练深度神经网络的技术,但是我们对其有效性的真正原因仍然所知甚少. 输入分布的稳定性和 BN 的成功之间关系很小,BN 对训练过程更根本的影响是:它让优 ...