【BZOJ4552】排序(线段树,二分答案)

题面

BZOJ

题解

好神的题啊

直接排序我们做不到

怎么维护?

考虑一下,如果我们随便假设一个答案

怎么检验它是否成立?

把这个数设成\(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】排序(线段树,二分答案)的更多相关文章

  1. [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)

    题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...

  2. BZOJ 4552 [Tjoi2016&Heoi2016]排序 ——线段树 二分答案

    听说是BC原题. 好题,二分答案变成01序列,就可以方便的用线段树维护了. 然后就是区间查询和覆盖了. #include <map> #include <cmath> #inc ...

  3. [BZOJ 2653] middle(可持久化线段树+二分答案)

    [BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...

  4. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

  5. 洛谷$P2824\ [HEOI2016/TJOI2016]$ 排序 线段树+二分

    正解:线段树+二分 解题报告: 传送门$QwQ$ 昂着题好神噢我$jio$得$QwQQQQQ$,,, 开始看到长得很像之前考试题的亚子,,,然后仔细康康发现不一样昂$kk$,就这里范围是$[1,n]$ ...

  6. BZOJ4552:[TJOI2016&HEOI2016]排序(线段树,二分)

    Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他. 这个难题是这样子的:给出一个1到n的全排列,现在对这 ...

  7. [HEOI2016/TJOI2016]排序 线段树+二分

    [HEOI2016/TJOI2016]排序 内存限制:256 MiB 时间限制:6000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而 ...

  8. BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP

    题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...

  9. BZOJ 4552: [Tjoi2016&Heoi2016]排序 线段树 二分

    目录 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 update 10.6 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 /* //fang zhi ...

  10. 洛谷P4632 [APIO2018] New Home 新家(动态开节点线段树 二分答案 扫描线 set)

    题意 题目链接 Sol 这题没有想象中的那么难,但也绝对不简单. 首先把所有的询问离线,按照出现的顺序.维护时间轴来处理每个询问 对于每个询问\((x_i, y_i)\),可以二分答案\(mid\). ...

随机推荐

  1. ajax调用handler,使用HttpWebRequest访问WCF服务

    引言 随着手机及移动设备的普及,移动端的应用也进入了热潮.以前PC端的门户网站,大多也均推出了适配移动设备的网站或者APP,再差的也注册了个公众号.在移动应用开发中,目前据我所了解到的解决方案有:1. ...

  2. golang urlencode

    u := url.Values{} u.Set(") u.Set(") u.Set(,"mac":"38:a4:ed:fe:99:c8"}` ...

  3. Ubuntu配置Nginx虚拟主机和支持ThinkPHP

    [Nginx配置虚拟主机] 每一个 server { listen       80;         server_name  www.a.com; ..... } 就表示一台虚拟域名, 然后对应的 ...

  4. dnspython模块安装

    wget  http://www.dnspython.org/kits/1.12.0/dnspython-1.12.0.tar.gz tar -zxvf dnspython-1.12.0.tar.gz ...

  5. [Uva10294]Arif in Dhaka

    [Uva10294]Arif in Dhaka 标签: 置换 Burnside引理 题目链接 题意 有很多个珠子穿成环形首饰,手镯可以翻转和旋转,项链只能旋转.(翻转过的手镯相同,而项链不同) 有n个 ...

  6. java-redis集合数据操作示例(三)

    redis系列博文,redis连接管理类的代码请跳转查看<java-redis字符类数据操作示例(一)>. 一.集合类型缓存测试类 public class SetTest { /** * ...

  7. 高通ASOC中的codec驱动

    ASOC的出现是为了让codec独立于CPU,减少和CPU之间的耦合,这样同一个codec驱动就无需修改就可以匹配任何一款平台. 在Machine中已经知道,snd_soc_dai_link结构就指明 ...

  8. 使用Vue和thrift建立前后端交互的demo

    初识thrift thrift 是 facebook 于2007年开发的一款跨平台 RPC(Remote Procedure Call) 软件框架, 它可以在多种平台上进行无缝交互,数据传输使用二进制 ...

  9. Windows下如何硬盘安装Ubuntu

    一般来说,折腾双系统是每一位程序猿都有过的经历,如何在windows下安装双系统ubuntu呢?今天来给大家介绍一下如何直接在windows硬盘安装ubuntu,而不需要使用U盘或者光盘,或外置硬盘. ...

  10. Python——Web.py詳解

    ubuntu安裝Web.py sudo pip install web.py 測試代碼: import web urls = ( '/(.*)','hello' ) app = web.applica ...