题目

在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q 位置上的数字。

分析

二分答案,

把二分出的ans与原序列比较,小于ans的数改为-1,大于ans的数改为1。

对于输入的每一个修改,用线段树来处理。

最后求出\(q\)位上的数是-1还是1,然后接着二分。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=100005;
using namespace std;
int a[N],n,m,re[N][4],k,ans,lazy[N*5],_0[N*5],_1[N*5];
int down(int v,int mid,int l,int r)
{
if(lazy[v]==-1)
{
lazy[v*2+1]=lazy[v*2]=lazy[v];
_0[v*2]=mid-l+1;
_0[v*2+1]=r-(mid+1)+1;
_1[v*2]=0;
_1[v*2+1]=0;
}
if(lazy[v]==1)
{
lazy[v*2+1]=lazy[v*2]=lazy[v];
_1[v*2]=mid-l+1;
_1[v*2+1]=r-(mid+1)+1;
_0[v*2]=0;
_0[v*2+1]=0;
}
lazy[v]=0;
}
int put(int v,int l,int r,int x,int y)
{
if(l==r)
{
if(y==-1)
_0[v]=1;
else _1[v]=1;
return 0;
}
int mid=(l+r)/2;
if(x<=mid)
put(v*2,l,mid,x,y);
else
put(v*2+1,mid+1,r,x,y);
_0[v]=_0[v*2]+_0[v*2+1];
_1[v]=_1[v*2]+_1[v*2+1];
}
int get(int v,int l,int r,int x,int y)
{
if(l==x && r==y)
{
return _1[v];
}
int mid=(l+r)/2;
down(v,mid,l,r);
int o;
if(y<=mid)
o=get(v*2,l,mid,x,y);
else
if(x>mid)
o=get(v*2+1,mid+1,r,x,y);
else
o=get(v*2,l,mid,x,mid)+get(v*2+1,mid+1,r,mid+1,y);
_0[v]=_0[v*2]+_0[v*2+1];
_1[v]=_1[v*2]+_1[v*2+1];
return o;
}
int change(int v,int l,int r,int x,int y,int value)
{
if(y<x) return 0;
int mid=(l+r)/2;
if(l==x && r==y)
{
lazy[v]=value;
if(value<0)
{
_0[v]=r-l+1;
_1[v]=0;
}
else
{
_1[v]=r-l+1;
_0[v]=0;
}
return 0;
}
down(v,mid,l,r);
if(y<=mid)
change(v*2,l,mid,x,y,value);
else
if(x>mid)
change(v*2+1,mid+1,r,x,y,value);
else
change(v*2,l,mid,x,mid,value),change(v*2+1,mid+1,r,mid+1,y,value);
_0[v]=_0[v*2]+_0[v*2+1];
_1[v]=_1[v*2]+_1[v*2+1];
}
int find(int v,int l,int r,int x)
{
if(l==r)
{
return _0[v];
}
int mid=(l+r)/2;
down(v,mid,l,r);
int o;
if(x<=mid)
o=find(v*2,l,mid,x);
else
o=find(v*2+1,mid+1,r,x);
_0[v]=_0[v*2]+_0[v*2+1];
_1[v]=_1[v*2]+_1[v*2+1];
return o;
}
bool check(int x)
{
memset(lazy,0,sizeof(lazy));
memset(_0,0,sizeof(_0));
memset(_1,0,sizeof(_1));
for(int i=1;i<=n;i++)
{
int g=a[i]<=x?-1:1;
put(1,1,n,i,g);
}
for(int i=1;i<=m;i++)
{
int p1=get(1,1,n,re[i][2],re[i][3]);
if(!re[i][1])
{
change(1,1,n,re[i][2],re[i][3]-p1,-1);
change(1,1,n,re[i][3]-p1+1,re[i][3],1);
}
else
{
change(1,1,n,re[i][2],re[i][2]+p1-1,1);
change(1,1,n,re[i][2]+p1,re[i][3],-1);
}
}
if(find(1,1,n,k))
return true;
else return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&re[i][1],&re[i][2],&re[i][3]);
}
scanf("%d",&k);
int l=1,r=n;
while(l<r)
{
int mid=(l+r)/2;
if(check(mid))
{
r=mid;
}
else
{
l=mid+1;
}
}
printf("%d",l);
}

【bzoj4552】【Tjoi2016&Heoi2016】【NOIP2016模拟7.12】排序的更多相关文章

  1. bzoj千题计划128:bzoj4552: [Tjoi2016&Heoi2016]排序

    http://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案 把>=mid 的数看做1,<mid 的数看做0 这样升序.降序排列相当于 ...

  2. 【bzoj 4554】【Tjoi2016&Heoi2016】【NOIP2016模拟7.12】游戏

    题目 分析 当没有石头的时候,就用二分图匹配来做. 但现在加入了石头, 所以,求出每行和每列联通快的个数,如果有一块平地,包括在某个行联通块以及某个列联通块中,连边. //无聊打了网络流,匈牙利也可以 ...

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

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

  4. BZOJ4552 [Tjoi2016&Heoi2016]排序 【二分 + 线段树】

    题目链接 BZOJ4552 题解 之前去雅礼培训做过一道题,\(O(nlogn)\)维护区间排序并能在线查询 可惜我至今不能get 但这道题有着\(O(nlog^2n)\)的离线算法 我们看到询问只有 ...

  5. [bzoj4552][Tjoi2016][Heoi2016]排序

    Description 给出一个$1$到$n$的全排列,现在对这个全排列序列进行$m$次局部排序,排序分为$2$种: $1.(0,l,r)$表示将区间$[l,r]$的数字升序排序; $2.(1,l,r ...

  6. BZOJ4552: [Tjoi2016&Heoi2016]排序

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

  7. [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树

    Brief Description DZY有一个数列a[1..n],它是1∼n这n个正整数的一个排列. 现在他想支持两种操作: 0, l, r: 将a[l..r]原地升序排序. 1, l, r: 将a ...

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

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

  9. 2018.08.01 BZOJ4552: [Tjoi2016&Heoi2016]排序(二分+线段树)

    传送门 线段树简单题. 二分答案+线段树排序. 实际上就是二分答案mid" role="presentation" style="position: relat ...

随机推荐

  1. 大sd卡 裂开了,写保护掉了。重新装好后,被写保护的解决办:

    大sd卡 裂开了,写保护掉了.重新装好后,被写保护的解决办: 1.用烙铁把写保护附近的塑料往外顶一点点,就ok   别太热,也别劲太大.容易过,不能破坏原来的部分. 解决问题. 总结: 写保护,就是检 ...

  2. 中国MOOC_零基础学Java语言_第2周 判断_2信号报告

    2 信号报告(5分) 题目内容: 无线电台的RS制信号报告是由三两个部分组成的: R(Readability) 信号可辨度即清晰度. S(Strength)    信号强度即大小. 其中R位于报告第一 ...

  3. Delphi DbgridEh实现鼠标拖动选中列,并使复选框选中

    1.先设置表格列的属性 procedure TForm_TaskToDW.InitGrid;var  MyCol: TColumnEh;begin  with DBGridEh_Task do  be ...

  4. 【Airtest】由于Airtest中long_click无法实现长按,教你如何在Airtest中实现长按的方法

    Airtest中我们想要实现长按操作,poco中有一个方法long_click,但是实际使用了一下,发现并没有卵用,仍然是单击操作,如下图 那我们要如何进行长按操作呢?其实可以利用swipe实现,以长 ...

  5. 从零构建vue项目(三)--vue常用插件

    一.直接拉取的模板中,package.json如下: { "name": "vuecli2-test", "version": " ...

  6. Java中字母大小写的转换

    例:String str = "AbC"; 把字符串所有字母变成小写: System.out.println(str.toLowerCase()); 把字符串所有字母大写: Sys ...

  7. 第五周课程总结&实验报告(三)

    实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档: 实验内容 1.已知字符串:"this is a test of java".按要求执 ...

  8. Nginx代理自动上线下线

    Nginx基于连接探测,如果发现后端异常,在单位周期为fail_timeout设置的时间,中达到max_fails次数,这个周期次数内,如果后端同一个节点不可用,那么接将把节点标记为不可用,并等待下一 ...

  9. GCC 编译参数

    -s 这个参数会把符号表从最终的可执行文件中删除.没有符号表,你就不能用gdb调试了,但是程序会更小 -O0 不做任何优化,这是默认的编译选项 -c 只编译不链接,产生.o文件,就是obj文件,不产生 ...

  10. [19/10/14-星期一] Python中的对象和类

    一.面向对象 ## 什么是对象? - 对象是内存中专门用来存储数据的一块区域. - 对象中可以存放各种数据(比如:数字.布尔值.代码) - 对象由三部分组成: 1.对象的标识(id) 2.对象的类型( ...