【Luogu】P2824排序(二分答案+线段树排序)
震惊!两个线段树和一个线段树竟是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排序(二分答案+线段树排序)的更多相关文章
- [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的全排列,现在对这 ...
- 【BZOJ4552】【HEOI2016】排序 [二分答案][线段树]
排序 Time Limit: 60 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 在2016年,佳媛姐姐喜欢上了数字序列 ...
- HDU 5649 DZY Loves Sorting(二分答案+线段树/线段树合并+线段树分割)
题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \le ...
- [HEOI2016/TJOI2016] 排序 解题报告(二分答案/线段树分裂合并+set)
题目链接: https://www.luogu.org/problemnew/show/P2824 题目描述: 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在 ...
- [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)
二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可 然后询问第q个位置的值,为1说明>=mid,以上 时间复杂度O(nlog2 ...
- YbtOJ#463-序列划分【二分答案,线段树,dp】
正题 题目链接:https://www.ybtoj.com.cn/problem/463 题目大意 给出长度为\(n\)的序列\(A,B\).要求划分成若干段满足 对于任何\(i<j\),若\( ...
- BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树
BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树 题意:给出每个果汁的价格p,美味度d,最多能放的体积l.定义果汁混合后的美味度为果汁的美味度的最小值. m次询问,要求花费不大于g, ...
随机推荐
- Android(java)学习笔记84:SQLiteDatabase的query方法参数
1. SQLiteDatabase的query方法: public Cursor query (boolean distinct, String table, String[] columns, St ...
- 2017.12.25 Java中面向对象思想的深刻理解
今日内容介绍 1.面向对象思想 2.类与对象的关系 3.局部变量和成员变量的关系 4.封装思想 5.private,this关键字 6.随机点名器 01面向对象和面向过程的思想 * A: 面向过程与面 ...
- 在maven项目中 配置代理对象远程调用crm
1 在maven项目中配置代理对象远程调用crm 1.1 在项目的pom.xml中引入CXF的依赖 <dependency> <groupId>org.apache.cxf&l ...
- C# 文件操作 常用的类
File------实用类,提供许多静态方法,用于移动.删除.和复制文件. Directory------实用类,提供许多静态方法,用于移动.删除和复制目录. Path------ 实用类,用于处理路 ...
- Oracle 函数 之 wm_concat()
wm_concat() 把列转换成一行一列显示,使用wm_concat函数可以显示在一行一列. --1 建表 create table province_city ( province varchar ...
- 使用FreeMarker导出word文档(支持导出图片)
一.添加maven依赖,导入FreeMarker所需要的jar包 <dependency> <groupId>org.freemarker</groupId> &l ...
- k8s的认证和service account简述
k8s的认证: 与API server通信的客户端大致有两类: 1.集群客户端工具(kubectl.kubeadm.kubelet等) 2.集群内pod. 任何客户端访问k8s时的过程: 1.认 ...
- Mysql数据库的权限、索引基本操作
数据库的关闭方法: .优雅的关闭数据库的方法: mysqladmin -uroot -p123456 shutdown .脚本关闭: /etc/init.d/mysqld stop .使用kill信号 ...
- 关于Linux系统下zookeeper集群的搭建
1.集群概述 1.1什么是集群 1.1.1集群概念 集群是一种计算机系统, 它通过一组松散集成的计算机软件和/或硬件连接起来高度紧密地协作完成计算工作.在某种意义上,他们可以被看作是一台计算机.集群系 ...
- java+Mysql大数据的一些优化技巧
众所周知,java在处理数据量比较大的时候,加载到内存必然会导致内存溢出,而在一些数据处理中我们不得不去处理海量数据,在做数据处理中,我们常见的手段是分解,压缩,并行,临时文件等方法; 例如,我们要将 ...