题目链接

  震惊!两个线段树和一个线段树竟是50分的差距!

  本题可以使用二分答案,二分那个位置上最后是什么数。怎么验证呢?

  把原序列改变,大于等于mid的全部变成1,小于mid的全部变成0,之后线段树排序。

  最后看那个位置上是1还是0,若是1则说明最后那个位置上是个>=mid的数。

#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#define left (rt<<1)
#define right (rt<<1|1)
#define mid ((l+r)>>1)
#define lson l,mid,left
#define rson mid+1,r,right
#define maxn 300030
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Que{
int opt,from,to;
}q[maxn]; int d[maxn],w[maxn]; int tree[maxn*],mem[maxn*],tag[maxn*];
inline void pushup(int rt){ tree[rt]=tree[left]+tree[right]; }
inline void build(int l,int r,int rt){
tree[rt]=mem[rt]=tag[rt]=;
if(l==r){
tree[rt]=w[l];
//printf("%d %d\n",l,w[l]);
return;
}
build(lson);
build(rson);
pushup(rt);
}
inline void pushdown(int rt,int m){
if(mem[rt]==&&tag[rt]==) return;
if(mem[rt]){
mem[left]=mem[right]=;
tree[left]=tree[right]=;
tag[left]=tag[right]=;
mem[rt]=;
}
if(tag[rt]){
tag[left]+=tag[rt]; tag[right]+=tag[rt];
tree[left]+=m-(m>>);
tree[right]+=m>>;
tag[rt]=;
}
return;
}
void update(int from,int to,int l,int r,int rt){
if(from<=l&&to>=r){
tag[rt]++;
tree[rt]+=r-l+;
return;
}
pushdown(rt,r-l+);
if(from<=mid) update(from,to,lson);
if(to>mid) update(from,to,rson);
pushup(rt);
}
void memdate(int from,int to,int l,int r,int rt){
if(from<=l&&to>=r){
tag[rt]=; mem[rt]=;
tree[rt]=;
return;
}
pushdown(rt,r-l+);
if(from<=mid) memdate(from,to,lson);
if(to>mid) memdate(from,to,rson);
pushup(rt);
}
int query(int from,int to,int l,int r,int rt){
if(from<=l&&to>=r) return tree[rt];
pushdown(rt,r-l+);
int ans=;
if(from<=mid) ans+=query(from,to,lson);
if(to>mid) ans+=query(from,to,rson);
return ans;
} bool check(int lim,int n,int m,int last){
build(,n,);
for(int i=;i<=m;++i){
int opt=q[i].opt,from=q[i].from,to=q[i].to;
int c1=query(from,to,,n,);
int c2=to-from+-c1;
//printf("%d %d<<\n",c1,c2);
memdate(from,to,,n,);
if(opt==) update(from+c2,to,,n,);
else update(from,from+c1-,,n,);
}
//printf("zero\n");
//for(int i=1;i<=n;++i) printf("%d ",zero.query(i,i,1,n,1));
//printf("\none\n");
//for(int i=1;i<=n;++i) printf("%d ",one.query(i,i,1,n,1));
//printf("\n");
return query(last,last,,n,);
} int main(){
int n=read(),m=read();
for(int i=;i<=n;++i) d[i]=read();
for(int i=;i<=m;++i) q[i]=(Que){read(),read(),read()};
int last=read();
int l=,r=n,ans=;
while(l<=r){
//printf("%d %d %d\n",l,r,mid);
for(int i=;i<=n;++i)
if(d[i]>=mid) w[i]=;
else w[i]=;
//for(int i=1;i<=n;++i) printf("%d<",w[i]);
//printf("\n");
if(check(mid,n,m,last)){
ans=mid;
l=mid+;
}
else r=mid-;
}
printf("%d",ans);
return ;
}

【Luogu】P2824排序(二分答案+线段树排序)的更多相关文章

  1. [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)

    解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...

  2. bzoj 4552 [Tjoi2016&Heoi2016]排序 (二分答案 线段树)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 题意: 给你一个1-n的全排列,m次操作,操作由两种:1.将[l,r]升序排序,2 ...

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

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

  4. 【BZOJ4552】【HEOI2016】排序 [二分答案][线段树]

    排序 Time Limit: 60 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 在2016年,佳媛姐姐喜欢上了数字序列 ...

  5. HDU 5649 DZY Loves Sorting(二分答案+线段树/线段树合并+线段树分割)

    题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \le ...

  6. [HEOI2016/TJOI2016] 排序 解题报告(二分答案/线段树分裂合并+set)

    题目链接: https://www.luogu.org/problemnew/show/P2824 题目描述: 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在 ...

  7. [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)

    二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可 然后询问第q个位置的值,为1说明>=mid,以上 时间复杂度O(nlog2 ...

  8. YbtOJ#463-序列划分【二分答案,线段树,dp】

    正题 题目链接:https://www.ybtoj.com.cn/problem/463 题目大意 给出长度为\(n\)的序列\(A,B\).要求划分成若干段满足 对于任何\(i<j\),若\( ...

  9. BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树

    BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树 题意:给出每个果汁的价格p,美味度d,最多能放的体积l.定义果汁混合后的美味度为果汁的美味度的最小值. m次询问,要求花费不大于g, ...

随机推荐

  1. modprobe与insmod的区别

    linux设备驱动有两种加载方式insmod和modprobe,下面谈谈它们用法上的区别1.insmod一次只能加载特定的一个设备驱动,且需要驱动的具体地址.写法为:        insmod dr ...

  2. Spring学习记录(一)

    1.Spring简介 Spring是一个轻量级的java开发框架.框架的主要优势之一就是分层架构,Spring使用基本的JavaBean,不仅限于服务器的开发.从简单性,可测试性和松耦合的角度而言,任 ...

  3. sql注入问题 java中将MySQL的数据库验证秘密加上 ' or '1'= '1 就可以出现万能密码

    password的字符串中,加上 ' or '1'= '1 就可以制作出万能密码. 原因如下: 原代码中密码是123456 执行数据库查询语句 实际上执行的SQL语句是: select * from ...

  4. html +css 登陆框中加用户图片,并设置登陆名不盖住图标

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 1- vue django restful framework 打造生鲜超市

    Vue+Django REST framework实战 使用Python3.6与Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站 项目支持支 ...

  6. JAVA使用JDBC连接,修改MySQL数据库(比较乱)

    原文地址1(连接MySQL图文) : http://www.cnblogs.com/GarfieldEr007/p/5746137.html 原文地址2 (修改MySQL图文): http://www ...

  7. web开发框架Flask学习二

    jinja2模板规范 在当前项目中创建一个文件为templates的文件夹,将其设置为模板文件夹,新建的html为模板页面, 在视图函数中使用render_template(".html的文 ...

  8. 9、python中的控制流

    学习完python的基础与数据后,我们就可以编写一些简单的命令了.但这时我们发现,目前位置写出来的程序都是自上而下顺序地执行的.要想程序改变这种自上而下的流程多一点变化,我们就要学习三种程序中的语句. ...

  9. unity安装记录

    官网直接下载(http://unity3d.com/cn/) 下载完后,会要求输入账号密码.我是先在官网进行一个账号注册,然后登陆即可. 首先会要你输入一个已有的邮箱,进行认证.进入自己邮箱,点击链接 ...

  10. vba通过函数调用Winrar压缩软件压缩文件

    Dim site As String        Dim FolderName As String        Dim FolderName1 As String        Dim Rarex ...