排序

Time Limit: 60 Sec  Memory Limit: 256 MB
[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表示局部排序的次数。
  第二行为n个整数,表示1到n的一个全排列。
  接下来输入m行,每一行有三个整数op, l, r,
   op为0代表升序排序,op为1代表降序排序, l, r 表示排序的区间。
  最后输入一个整数q,q表示排序完之后询问的位置。

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

HINT

  1 <= n <= 10^5,1 <= m <= 10^5, 1 <= q <= n。

Solution

  我们先考虑如果权值很小的话怎么做,显然可以对每个权值开一个线段树维护在哪些位置出现过。

  那么排序显然就是覆盖连续的一段。只要知道某一区间有几个这个权值即可。

  但是这样显然是过不了的,于是我们考虑二分答案,把val >= mid的设为1,其余的设为0

  这样就把权值变成了0/1,那么显然我们按照以上操作,如果Q位置上是1说明mid<=Ans还可以更大一点否则说明mid>Ans

  只要支持区间求和以及区间覆盖0/1即可。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE = ;
const int MOD = 1e9 + ; int get()
{
int res = , Q = ; char c;
while( (c = getchar()) < || c > )
if(c == '-') Q = -;
if(Q) res = c - ;
while( (c = getchar()) >= && c <= )
res = res * + c - ;
return res * Q;
} int n, m, Q;
int a[ONE];
int res, now; struct power
{
struct point
{
int val, tag;
}Node[ONE]; void Build(int i, int l, int r)
{
Node[i].tag = -;
if(l == r) return;
int mid = l + r >> ;
Build(i << , l, mid);
Build(i << | , mid + , r);
} int pushdown(int i, int l, int r)
{
int mid = l + r >> ;
if(Node[i].tag != -)
{
Node[i << ].tag = Node[i].tag;
Node[i << ].val = Node[i].tag * (mid - l + );
Node[i << | ].tag = Node[i].tag;
Node[i << | ].val = Node[i].tag * (r - (mid + ) + );
Node[i].tag = -;
}
} void Update(int i, int l, int r, int L, int R, int x)
{
if(L > R) return;
if(L <= l && r <= R)
{
Node[i].tag = x;
Node[i].val = x * (r - l + );
return;
}
pushdown(i, l, r);
int mid = l + r >> ;
if(L <= mid) Update(i << , l, mid, L, R, x);
if(mid + <= R) Update(i << | , mid + , r, L, R, x);
Node[i].val = Node[i << ].val + Node[i << | ].val;
} void Query(int i, int l, int r, int L, int R)
{
if(L > R) return;
if(L <= l && r <= R)
{
res += Node[i].val;
return;
}
pushdown(i, l, r);
int mid = l + r >> ;
if(L <= mid) Query(i << , l, mid, L, R);
if(mid + <= R) Query(i << | , mid + , r, L, R);
}
}C[]; struct operate
{
int l, r, x;
}oper[ONE]; void Modify(int id, int Left, int Right)
{
res = ;
C[id].Query(, , n, Left, Right);
C[id].Update(, , n, Left, Right, );
C[id].Update(, , n, now, now + res - , );
now += res;
} int Check(int mid)
{
for(int i = ; i <= ; i++)
C[i].Node[].tag = ; for(int i = ; i <= n; i++)
C[a[i] >= mid].Update(, , n, i, i, ); for(int i = ; i <= m; i++)
{
now = oper[i].l;
if(oper[i].x == ) for(int id = ; id <= ; id++) Modify(id, oper[i].l, oper[i].r);
if(oper[i].x == ) for(int id = ; id >= ; id--) Modify(id, oper[i].l, oper[i].r);
} res = , C[].Query(, , n, Q, Q);
return res;
} int main()
{
n = get(); m = get();
for(int i = ; i <= n; i++)
a[i] = get();
for(int i = ; i <= m; i++)
oper[i].x = get(), oper[i].l = get(), oper[i].r = get(); Q = get();
int l = , r = n;
while(l < r - )
{
int mid = l + r >> ;
if(Check(mid)) l = mid;
else r = mid;
} if(Check(r)) printf("%d", r);
else printf("%d", l);
}

  

【BZOJ4552】【HEOI2016】排序 [二分答案][线段树]的更多相关文章

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

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

  2. bzoj 4552 [Tjoi2016&Heoi2016]排序 (二分答案 线段树)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 题意: 给你一个1-n的全排列,m次操作,操作由两种:1.将[l,r]升序排序,2 ...

  3. BZOJ 4552 [Tjoi2016&Heoi2016]排序 | 二分答案 线段树

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

  4. HDU 5649 DZY Loves Sorting(二分答案+线段树/线段树合并+线段树分割)

    题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \le ...

  5. [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)

    二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可 然后询问第q个位置的值,为1说明>=mid,以上 时间复杂度O(nlog2 ...

  6. [HEOI2016/TJOI2016] 排序 解题报告(二分答案/线段树分裂合并+set)

    题目链接: https://www.luogu.org/problemnew/show/P2824 题目描述: 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在 ...

  7. 【Luogu】P2824排序(二分答案+线段树排序)

    题目链接 震惊!两个线段树和一个线段树竟是50分的差距! 本题可以使用二分答案,二分那个位置上最后是什么数.怎么验证呢? 把原序列改变,大于等于mid的全部变成1,小于mid的全部变成0,之后线段树排 ...

  8. bzoj 4552 [Tjoi2016&Heoi2016]排序——二分答案

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案,把 >= mid 的设成1.< mid 的设成0,之后排序就变成 ...

  9. YbtOJ#463-序列划分【二分答案,线段树,dp】

    正题 题目链接:https://www.ybtoj.com.cn/problem/463 题目大意 给出长度为\(n\)的序列\(A,B\).要求划分成若干段满足 对于任何\(i<j\),若\( ...

随机推荐

  1. iOS- Swift:如何使用iOS8中的UIAlertController

    1.前言 在前段时间手机QQ:升级iOS8.3后,发图就崩的情况, 就是因为iOS8更新UIAlertController后,仍然使用UIAlertview导致的 具体原因分析 这个可以看腾讯团队发出 ...

  2. 安装libvirt管理套件(C/S架构模式,用户管理kvm虚拟机)

    # 1:安装程序包 yum install -y libvirt virt-manager virt-viewer virt-install qemu-kvm   # 2:启动libvirtd守护进程 ...

  3. nginx 二进制安装

    Nginx的安装方法 1:yum安装 默认是1.6版本,且在epel源中   2:源码包编译安装 源码下载:http://nginx.org/en/download.html,下载1.8稳定版本   ...

  4. js滚动异步加载数据的思路

    <body> <div style="width:200px; height:1000px; border:1px solid red;" id="to ...

  5. [翻译]API Guides - Layouts

    官方文档地址:http://developer.android.com/guide/topics/ui/declaring-layout.html PS:API Guides里面的内容不免都简单些,翻 ...

  6. sharepoint content type publishing

    1. Create 1 Project Team sites (Site1) on SharePoint(可以用普通site)2. Go to http://<PCName>:8080/_ ...

  7. vscode如何用浏览器预览运行html文件

    1,打开vscode编辑器,点击编辑器主界面左上侧第五个小图标——‘扩展’按钮: 2,进入扩展搜索右拉框,在应用商店搜索框中输入“view in browser”会自动进行搜索 3,等待几秒钟时间,扩 ...

  8. 【数据库】SQL两表之间:根据一个表的字段更新另一个表的字段

    1. 写法轻松,更新效率高:update table1 set field1=table2.field1,field2=table2.field2from table2where table1.id= ...

  9. 解决Mac下npm权限问题

    前言 在学习Vue-CLI3的时候使用了全局安装,提示安装失败,本以为是npm版本问题,在更新npm的过程中又出现了 npm ERR! code: 'EACCES' ,查了一下发现是权限问题. 看到权 ...

  10. Importing/Indexing database (MySQL or SQL Server) in Solr using Data Import Handler--转载

    原文地址:https://gist.github.com/maxivak/3e3ee1fca32f3949f052 Install Solr download and install Solr fro ...