【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, ...
随机推荐
- ArrayList集合例题,商品库存管理(集合)
创建车库集合,存进车 public class demo1 { String pinpai; String c; int s; } import java.util.ArrayList; class ...
- 方法 -------JavaScript
本文摘要:http://www.liaoxuefeng.com/ 在一个对象中绑定函数,称为这个对象的方法. 在JavaScript的中,对象的定义是这样的: var xiaoming = { nam ...
- C#箴言之用属性来访问类的私有成员
在程序中,难免要访问某个对象的私有成员.那么以前实现这类功能的方法有两种,第一种方法最简单,就是把成员访问符从“private”改为“public”即可:而另一个就是提供公有的成员访问函数来进行访问. ...
- 为啥国内互联网公司都用centos而不是ubuntu?
一直以来都很好奇ubuntu和centos有啥区别,上学时接触的都是ubuntu,自己每次装virtual box的时候都会下个ubuntu,但是公司的服务器上装的都是centos,今天查了下知乎网友 ...
- Java代码随机生成图片验证码
package com.rchm.util.images; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2 ...
- node.js express环境下中文需要注意的地方
问题一: 最近在nuxt项目中开始着手把一些跨域的请求转移到express里,其实跟其他语言差不多,http对象发请求,接收请求都写得很顺畅.之前用的请求部分大多数是get请求,所以除了注意编码问题之 ...
- js控制台输出图案
控制台输出图案 console.log([ " _ooOoo_", " o8888888o", " 88\" . \"88&quo ...
- 微信在浏览器打开前的提示页面Android与IOS判断
直接在网上扒一个页面,分分钟搞定! 先看一下效果 这是用微信开发工具打开的样式,直接上完整代码 <!DOCTYPE html> <html lang="en"& ...
- Gym - 101908G Gasoline 二分+最大流
G - Gasoline Gym - 101908G 题意:给出R个提供点,P个接收点,每个接收点都要接收满,还有一个运输的时间,问最小时间能够完成所有的运输 题解:首先每次都必须要满流,所以我们只要 ...
- 笔记-python-__new__()
笔记-python-__new__() 1. __new__() __new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前. 验证代码: class Person(obj ...