【BZOJ4552】排序(线段树,二分答案)
【BZOJ4552】排序(线段树,二分答案)
题面
题解
好神的题啊
直接排序我们做不到
怎么维护?
考虑一下,如果我们随便假设一个答案
怎么检验它是否成立?
把这个数设成\(1\),其他的数字都设成\(0\)
最后检查一下这个位置是不是\(1\)就好啦
但是这样没法排序
那么,我们考虑二分一个答案,
把所有比\(mid\)大的数都设成\(1\)
这样,如果在第\(Q\)位上的数字是\(1\)
意味着有一个不小于当前\(mid\)的数在这个位置上
否则就是一个比\(mid\)小的数在这个位置上
这样就可以二分答案啦
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 222222
#define lson (now<<1)
#define rson (now<<1|1)
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Work{int l,r,opt;}p[MAX];
int t[MAX<<2],tag[MAX<<2];
int a[MAX],b[MAX],n,m,Q;
void Build(int now,int l,int r)
{
tag[now]=-1;
if(l==r){t[now]=b[l];return;}
int mid=(l+r)>>1;
Build(lson,l,mid);Build(rson,mid+1,r);
t[now]=t[lson]+t[rson];
}
void puttag(int now,int l,int r,int w)
{
tag[now]=w;
t[now]=(r-l+1)*w;
}
void pushdown(int now,int l,int r)
{
if(tag[now]==-1)return;
int mid=(l+r)>>1;
puttag(lson,l,mid,tag[now]);
puttag(rson,mid+1,r,tag[now]);
tag[now]=-1;
}
int Query(int now,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return t[now];
pushdown(now,l,r);
int ret=0,mid=(l+r)>>1;
if(L<=mid)ret+=Query(lson,l,mid,L,R);
if(R>mid)ret+=Query(rson,mid+1,r,L,R);
return ret;
}
void Modify(int now,int l,int r,int L,int R,int w)
{
if(L<=l&&r<=R){puttag(now,l,r,w);return;}
pushdown(now,l,r);
int mid=(l+r)>>1;
if(L<=mid)Modify(lson,l,mid,L,R,w);
if(R>mid)Modify(rson,mid+1,r,L,R,w);
t[now]=t[lson]+t[rson];
}
void Work(int i)
{
int ss=Query(1,1,n,p[i].l,p[i].r);
if(p[i].opt==0)
{
ss=p[i].r-p[i].l+1-ss;
if(ss!=0)Modify(1,1,n,p[i].l,p[i].l+ss-1,0);
if(ss!=p[i].r-p[i].l+1)Modify(1,1,n,p[i].l+ss,p[i].r,1);
}
else
{
if(ss!=0)Modify(1,1,n,p[i].l,p[i].l+ss-1,1);
if(ss!=p[i].r-p[i].l+1)Modify(1,1,n,p[i].l+ss,p[i].r,0);
}
}
bool check(int mid)
{
for(int i=1;i<=n;++i)if(a[i]>=mid)b[i]=1;else b[i]=0;
Build(1,1,n);
for(int i=1;i<=m;++i)Work(i);
return Query(1,1,n,Q,Q);
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=m;++i)p[i].opt=read(),p[i].l=read(),p[i].r=read();
Q=read();
int l=1,r=n,ans=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}
【BZOJ4552】排序(线段树,二分答案)的更多相关文章
- [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)
题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...
- BZOJ 4552 [Tjoi2016&Heoi2016]排序 ——线段树 二分答案
听说是BC原题. 好题,二分答案变成01序列,就可以方便的用线段树维护了. 然后就是区间查询和覆盖了. #include <map> #include <cmath> #inc ...
- [BZOJ 2653] middle(可持久化线段树+二分答案)
[BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- 洛谷$P2824\ [HEOI2016/TJOI2016]$ 排序 线段树+二分
正解:线段树+二分 解题报告: 传送门$QwQ$ 昂着题好神噢我$jio$得$QwQQQQQ$,,, 开始看到长得很像之前考试题的亚子,,,然后仔细康康发现不一样昂$kk$,就这里范围是$[1,n]$ ...
- BZOJ4552:[TJOI2016&HEOI2016]排序(线段树,二分)
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他. 这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- [HEOI2016/TJOI2016]排序 线段树+二分
[HEOI2016/TJOI2016]排序 内存限制:256 MiB 时间限制:6000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而 ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
- BZOJ 4552: [Tjoi2016&Heoi2016]排序 线段树 二分
目录 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 update 10.6 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 /* //fang zhi ...
- 洛谷P4632 [APIO2018] New Home 新家(动态开节点线段树 二分答案 扫描线 set)
题意 题目链接 Sol 这题没有想象中的那么难,但也绝对不简单. 首先把所有的询问离线,按照出现的顺序.维护时间轴来处理每个询问 对于每个询问\((x_i, y_i)\),可以二分答案\(mid\). ...
随机推荐
- 【特性】select语句中使用字符串链接获取字段值失败
坑1 在一个多行的表中,想把其中的一个字段值拿出来,组成一个字符串供后面使用. 按照以往,自己就如以下这么写了: declare @sql varchar(8000) set @sql='insert ...
- HTTP入门
请求报文图解: 请求报文 图片 响应报文图解: 响应报文
- SSM项目手动分页详解
环境:idea+mysql 首先,既然是mysql,那肯定会用到limit,用这个分页的确很方便. 第一步,编写sql语句 <select id="selectImages" ...
- WPF ----在UserControl的xaml里绑定依赖属性
场景:在定义wpf 用户控件的时候,希望使用时设置自定义的属性来改变用户控件里的状态或内容等. 下面直接上实例代码: 用户控件的后台代码,定义依赖属性 public partial class MyU ...
- Swift百万线程攻破单例(Singleton)模式
一.不安全的单例实现 在上一篇文章我们给出了单例的设计模式,直接给出了线程安全的实现方法.单例的实现有多种方法,如下面: class SwiftSingleton { class var shared ...
- spring 组件@Scope(request,session)示例
上回说到, spring组件的注解Scope大约有singleton.prototype.request.session.global session 这么几种常用的场景.这里需要特别说明一下,根据源 ...
- ERROR namenode.NameNode: Failed to start namenode. java.lang.IllegalArgument
这个问题一般是配置文件配置没有配置好的原因
- Nginx和Apache有什么区别?
Nginx抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能. Apache rewrite ,比nginx 的rewrite ...
- hihoCoder 1523 数组重排2 贪心
题意:给定一个1-N的排列A1, A2, - AN,每次操作小Hi可以选择一个数,把它放到数组的最左边. 请计算小Hi最少进行几次操作就能使得新数组是递增排列的. 思路:最后的序列是递增的,那么必定满 ...
- 使用lambda编程之延迟执行
使用lambda表达式的主要原因是,将代码的执行延迟到一个合适的时间点. 所有的lambda表达式都是延迟执行的.毕竟,如果你希望立即执行一段代码,那就没有必要使用lambda表达式了.延迟执行代码的 ...