BZOJ4552 Tjoi2016&Heoi2016排序 【二分+线段树】*
Description
在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q位置上的数字。
Input
输入数据的第一行为两个整数n和m。n表示序列的长度,m表示局部排序的次数。1 <= n, m <= 10^5第二行为n个整数,表示1到n的一个全排列。接下来输入m行,每一行有三个整数op, l, r, op为0代表升序排序,op为1代表降序排序, l, r 表示排序的区间。最后输入一个整数q,q表示排序完之后询问的位置, \(1 <= q <= n。1 <= n <= 10^5,1 <= m <= 10^5\)
Output
输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第q位置上的数字。
Sample Input
6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
Sample Output
5
首先发现一个性质,这个答案是可以二分的 这是为啥啊?
然后二分之后我们就可以把所有小于等于mid的数变成0,大于等于mid的数变成1,然后对区间排序就变成了分别赋值0和1,就变成区间修改操作了,于是可以用线段树维护出来,如果发现第k位上是0那么说明l可能可以变大,否则r必须变小
然后就直接二分维护就行了,注意modify的时候边界问题
#include<bits/stdc++.h>
using namespace std;
#define fu(a,b,c) for(int a=b;a<=c;++a)
#define N 100010
#define LD (t<<1)
#define RD (t<<1|1)
int a[N],b[N],n,m,k;
int l[N],r[N],typ[N];
int siz[N<<2],chg[N<<2];
void pushup(int t){siz[t]=siz[LD]+siz[RD];}
void pushdown(int t,int l,int r){
if(l==r)return;
if(chg[t]!=-1){
int mid=(l+r)>>1;
if(l<=mid)chg[LD]=chg[t],siz[LD]=(mid-l+1)*chg[t];
if(mid<r)chg[RD]=chg[t],siz[RD]=(r-mid)*chg[t];
chg[t]=-1;
}
}
void build(int t,int l,int r){
if(l>r)return;
chg[t]=-1;
if(l==r){siz[t]=b[l];return;}
int mid=(l+r)>>1;
build(LD,l,mid);
build(RD,mid+1,r);
pushup(t);
}
void modify(int t,int l,int r,int L,int R,int vl){
if(L>R)return;
if(L<=l&&r<=R){chg[t]=vl,siz[t]=(r-l+1)*vl;return;}
pushdown(t,l,r);
int mid=(l+r)>>1;
if(R<=mid)modify(LD,l,mid,L,R,vl);
else if(L>mid)modify(RD,mid+1,r,L,R,vl);
else modify(LD,l,mid,L,mid,vl),modify(RD,mid+1,r,mid+1,R,vl);
pushup(t);
}
int query(int t,int l,int r,int L,int R){
if(L<=l&&r<=R)return siz[t];
pushdown(t,l,r);
int mid=(l+r)>>1,ans=0;
if(R<=mid)ans=query(LD,l,mid,L,R);
else if(L>mid)ans=query(RD,mid+1,r,L,R);
else ans=query(LD,l,mid,L,mid)+query(RD,mid+1,r,mid+1,R);
pushup(t);
return ans;
}
bool check(int val){
fu(i,1,n)b[i]=(a[i]>=val);
build(1,1,n);
fu(i,1,m){
int s=query(1,1,n,l[i],r[i]);
if(typ[i]==0){
modify(1,1,n,l[i],r[i]-s,0);
modify(1,1,n,r[i]-s+1,r[i],1);
}else{
modify(1,1,n,l[i],l[i]+s-1,1);
modify(1,1,n,l[i]+s,r[i],0);
}
}
return query(1,1,n,k,k);
}
int main(){
scanf("%d%d",&n,&m);
fu(i,1,n)scanf("%d",&a[i]);
fu(i,1,m)scanf("%d%d%d",&typ[i],&l[i],&r[i]);
scanf("%d",&k);
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",ans);
return 0;
}
BZOJ4552 Tjoi2016&Heoi2016排序 【二分+线段树】*的更多相关文章
- [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树
Brief Description DZY有一个数列a[1..n],它是1∼n这n个正整数的一个排列. 现在他想支持两种操作: 0, l, r: 将a[l..r]原地升序排序. 1, l, r: 将a ...
- 【BZOJ4552】[Tjoi2016&Heoi2016]排序 二分+线段树
[BZOJ4552][Tjoi2016&Heoi2016]排序 Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ...
- bzoj 4552: [Tjoi2016&Heoi2016]排序——二分+线段树
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)
解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...
- bzoj千题计划128:bzoj4552: [Tjoi2016&Heoi2016]排序
http://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案 把>=mid 的数看做1,<mid 的数看做0 这样升序.降序排列相当于 ...
- BZOJ4552 [Tjoi2016&Heoi2016]排序 【二分 + 线段树】
题目链接 BZOJ4552 题解 之前去雅礼培训做过一道题,\(O(nlogn)\)维护区间排序并能在线查询 可惜我至今不能get 但这道题有着\(O(nlog^2n)\)的离线算法 我们看到询问只有 ...
- BZOJ4552:[TJOI2016&HEOI2016]排序(线段树,二分)
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他. 这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- 2018.08.01 BZOJ4552: [Tjoi2016&Heoi2016]排序(二分+线段树)
传送门 线段树简单题. 二分答案+线段树排序. 实际上就是二分答案mid" role="presentation" style="position: relat ...
- [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)
二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可 然后询问第q个位置的值,为1说明>=mid,以上 时间复杂度O(nlog2 ...
随机推荐
- Codeforces Round #365 (Div. 2) E - Mishka and Divisors(转化成01-背包)
http://codeforces.com/contest/703/problem/E 题意: 给出n个数和一个k,计算出至少要多少个数相乘才是k的倍数. 思路:这道题目参考了杭电大神的代码http: ...
- 模仿某旅行网站 纯css实现背景放大效果
基本功能是鼠标移动到图片上,对应宽度变宽.其中布局和基本样式直接copy官网,功能部分是自己瞎鼓捣实现的. 直接上代码: HTML部分 <div class="fold_wrap&qu ...
- ColKang v1.0
/* *2015.3.31 14:00更新 *上午刚写完这篇博客,下午就读到迭代器了.C++ primer中讲迭代器那节说道了->符号的意思,即(*ptr). 及将指针解引用之后再调用成员函数 ...
- MySQL表类型MyISAM/InnoDB的区别(解决事务不回滚的问题)
MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.与 ...
- [sping]xml配置文件中factory-bean与factory-method(spring使用工厂方法注入bean)
public class CarFactory { //非静态方法 public Car createCar(){ Car car = new Car(); car.setBrand("BM ...
- spring mvc: 多解析器映射(资源绑定视图解析器 + 内部资源[普通模式/]视图解析器)
spring mvc: 多解析器映射(资源绑定视图解析器 + 内部资源[普通模式/]视图解析器) 资源绑定视图解析器 + 内部资源(普通模式)视图解析器 并存方式 内部资源视图解析器: http:// ...
- addEventListener 和 onclick 简单比较
首先说一下addEventListener 语法: element.addEventListener(event, function, useCapture) 这里的event是事件名,functio ...
- [转载]Java生成Word文档
在开发文档系统或办公系统的过程中,有时候我们需要导出word文档.在网上发现了一个用PageOffice生成word文件的功能,就将这块拿出来和大家分享. 生成word文件与我们编辑word文档本质上 ...
- LeetCode OJ:Gas Station(加油站问题)
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...
- LeetCode OJ:Implement strStr()(实现子字符串查找)
Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle ...