4552: [Tjoi2016&Heoi2016]排序

Time Limit: 60 Sec  Memory Limit: 256 MB
Submit: 2703  Solved: 1386
[Submit][Status][Discuss]

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

这题直接排序肯定T到飞起,然后我们考虑其他做法(废话)
瞎yy仔细分析后这也是个区间问题阿,考虑能不能用线段树维护。
发现说是排序,但是最主要的关系还是之和大小关系有关啊,所以把这个问题抽象成一个01序列
我们可以二分答案,每次check都把所有操作重新进行一遍。这只是个大体思路,我们还要考虑其正确性。
为什么要二分答案,因为把问题转化成01序列后0或1代表该数与目标的大小关系,如果当前的该位置比目标大,那肯定是将区间左断点变大啊
至于决策单调性,博主比较mengbi。有大佬会可以指出阿
现在我们考虑怎么对每个更改进行操作,前面我们说过,01代表的是某个数与目标的大小关系,那我们在排序时只需利用这个性质,对于升序排序,把区间中所有0甩到左边,把1甩到右边,如果降序反过来。
这样我们在二分答案时只需检测询问位置是否为1即可。
对于这这些操作只需维护一棵支持区间覆盖,区间修改的线段数即可。
注意点:在懒标记下传和赋值时,要直接赋值而不是累加。
    要加特判(代码中有注释),因为check()函数中的 change(1,1,n,ql[i],ql[i]+num-1,1)会导致右端点小于左端点
 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
const int N=1e5+;
using namespace std;
int mid,sum1,q;
int n,m;
int a[N];
struct node{
int l,r,opt;
}ask[N];
struct NODE{
int l,r,val,f;
}tr[N<<];
void build(int p,int l,int r){//cout<<"B"<<endl;
tr[p].l=l,tr[p].r=r;
if(l==r){//cout<<"break"<<endl;
tr[p].f=-;
tr[p].val=(a[l]>=mid);
return ;
}
tr[p].f=-;
int mid=(l+r)>>;
build(p<<,l,mid);
build(p<<|,mid+,r);
tr[p].val=tr[p<<].val+tr[p<<|].val;
}
void down(int p){
if(tr[p].f<) return ;
tr[p<<].f=tr[p].f;
tr[p<<|].f=tr[p].f;//lanbiaojizhijiefugai
tr[p<<].val=(tr[p<<].r-tr[p<<].l+)*tr[p].f;
tr[p<<|].val=(tr[p<<|].r-tr[p<<|].l+)*tr[p].f;
tr[p].f=-;
}
void change(int p,int l,int r,int val){
if(l<=tr[p].l&&tr[p].r<=r){
tr[p].f=val;
tr[p].val=(tr[p].r-tr[p].l+)*val;//zhijiefuzhi//
return ;
}
if(l>tr[p].r||r<tr[p].l) return ;
down(p);
int mid=(tr[p].l+tr[p].r)>>;
if(l<=mid) change(p<<,l,r,val);
if(r>mid) change(p<<|,l,r,val);
tr[p].val=tr[p<<].val+tr[p<<|].val;
}
void query(int p,int l,int r){//cout<<p<<" "<<l<<" "<<r<<endl;
if(l<=tr[p].l&&tr[p].r<=r){//cout<<"break"<<endl;
sum1+=tr[p].val;//
return ;
}
if(l>tr[p].r||r<tr[p].l) return ;//特判
down(p);
int mid=(tr[p].l+tr[p].r)>>;
if(l<=mid)query(p<<,l,r);
if(r>mid)query(p<<|,l,r);
}
bool check(int x){
build(,,n);
for(int i=;i<=m;i++){
sum1=;query(,ask[i].l,ask[i].r);
if(ask[i].opt==){//升序
//cout<<"Q"<<endl;
change(,ask[i].l,ask[i].r-sum1,);//
change(,ask[i].r-sum1+,ask[i].r,);//
}
else{
//cout<<"Q"<<endl;
change(,ask[i].l+sum1,ask[i].r,);
change(,ask[i].l,ask[i].l+sum1-,);
}
}
//for(int i=1;i<=n;i++) cout<<tr[i].val<<" ";
sum1=;
query(,q,q);
//cout<<sum1<<endl;
if(sum1) return true;
else return false;
}
int main(){
//freopen("sort9.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=m;i++){
scanf("%d%d%d",&ask[i].opt,&ask[i].l,&ask[i].r);
}
scanf("%d",&q);
int l=,r=n,ans;
while(l<r){//cout<<"K"<<endl;
mid=(l+r)>>;//cout<<l<<" "<<r<<" "<<mid<<endl;
//cout<<check(mid)<<endl;
if(check(mid)) ans=mid/*?*/,l=mid+;
else r=mid;
}
printf("%d",ans);
}

[HEOI2016&TJOI2016] 排序(线段树)的更多相关文章

  1. [HEOI2016/TJOI2016]排序 线段树+二分

    [HEOI2016/TJOI2016]排序 内存限制:256 MiB 时间限制:6000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而 ...

  2. [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)

    题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...

  3. luoguP2824 [HEOI2016/TJOI2016]排序(线段树分裂做法)

    题意 所谓线段树分裂其实是本题的在线做法. 考虑如果我们有一个已经排好序的区间的权值线段树,那么就可以通过线段树上二分的方法得到第\(k\)个数是谁. 于是用set维护每个升序/降序区间的左右端点以及 ...

  4. 洛谷$P2824\ [HEOI2016/TJOI2016]$ 排序 线段树+二分

    正解:线段树+二分 解题报告: 传送门$QwQ$ 昂着题好神噢我$jio$得$QwQQQQQ$,,, 开始看到长得很像之前考试题的亚子,,,然后仔细康康发现不一样昂$kk$,就这里范围是$[1,n]$ ...

  5. BZOJ.4552.[HEOI2016/TJOI2016]排序(线段树合并/二分 线段树)

    题目链接 对于序列上每一段连续区间的数我们都可以动态开点建一棵值域线段树.初始时就是\(n\)棵. 对于每次操作,我们可以将\([l,r]\)的数分别从之前它所属的若干段区间中分离出来,合并. 对于升 ...

  6. Luogu P2824 [HEOI2016/TJOI2016]排序 线段树+脑子

    只会两个$log$的$qwq$ 我们二分答案:设答案为$ans$,则我们把$a[i]<=ans$全部设成$0$,把$a[i]>ans$全部设成$1$,扔到线段树里,这样区间排序(升序)就是 ...

  7. day 1 晚上 P2824 [HEOI2016/TJOI2016]排序 线段树

    #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #inclu ...

  8. 排序HEOI2016/TJOI2016 二分+线段树判定

    LINK:排序 此题甚好我一点思路都没有要是我当时省选此题除了模拟我恐怕想不到还可以二分 还可以线段树... 有点ex 不太好写 考虑 暴力显然每次给出询问我们都是可以直接sort的 无视地形无视一切 ...

  9. BZOJ4552 HEOI/TJOI2016 排序 线段树、二分答案

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 题意:给出一个$1$到$N$的全排列,对其进行$M$次排序,每次排序将区间$[l ...

  10. 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)

    2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...

随机推荐

  1. 菜单ACTION控制栏位字段编辑,点击菜单ACTION才能编辑指定的栏位

    范例(axmt500): 目的,控制新增的栏位(价格清单2),需点击菜单栏“修改价格清单2”才能对相应的栏位进行编辑修改,并记录修改人.日期: 1)在规格上增加新ACTION——action_modi ...

  2. python模块-paramiko-修改源码(demo实例)

    在github上下载一个paramiko,找到demos目录,复制到pycharm项目里面 这是因为python3传来得数据是bates数据类型,需要decode()一下就可以,在demos下得int ...

  3. 并不对劲的P5589

    题目大意 有\(n\)(\(n\leq 10^9\))个数:\(1,2,...,n\),每次操作是随机取一个没被删除的数\(x\),并删去\(x,x^2,x^3,...\). 求期望几次删完所有数. ...

  4. Linux下离线安装Docker最新版本

    一.基础环境1.操作系统:CentOS 7.32.Docker版本:18.06.1 官方下载地址(打不开可能需要梯子)3.百度云Docker 18.06.1地址:https://pan.baidu.c ...

  5. Eclipse错误提示: Symbol 'xxxx' could not be resolved

    在eclipse中安装maven(网上资源):https://zhinan.sogou.com/guide/detail/?id=1610049267 项目名 右键->configure-> ...

  6. C#int类型 转Byte[]

    方法1:使用左移和右移 int转化为byte[]:   public  byte[] intToBytes(int value)         {             byte[] src = ...

  7. springboot-oracle工程win下正常,centos下不能访问数据库

    工程在win下正常运行,部署到centos下出现下述异常: ### Error querying database. Cause: org.springframework.jdbc.CannotGet ...

  8. js之运算符(关系运算符)

    关系运算符用于测试两个值之间的关系,根据关系是否存在而返回true或者是false.关系表达式总是返回一个布尔值. 具有如下8个关系运算符:大于(>),小于(<),小于等于(<=), ...

  9. WebApi 跨域解决方案 --CORS

    跨站HTTP请求(Cross-site HTTP request)是指发起请求的资源所在域不同于请求指向的资源所在域的HTTP请求. 比如说,我在Web网站A(www.a.com)中通过<img ...

  10. Struts简介

    一.简介 Apache Struts 2最初被称为WebWork 2,它是一个简洁的.可扩展的框架,可用于创建企业级Java web应用程序.设计这个框架是为了从构建.部署.到应用程序维护方面来简化整 ...