4552: [Tjoi2016&Heoi2016]排序

链接

分析:

  因为只询问一次,所以考虑二分这个数。显然是没有单调性的,但是我们可以二分所有大于等于mid的数中,是否有满足条件的x(而不是之间判断mid是否满足条件)。

  那么将大于等于mid的数设为1,小于mid的数设为0,此时对区间排序就变得非常简单了,只需要线段树求一下区间内1的个数,给一段区间赋值即可。

  最后判断询问的位置是否是1,如果是1,说明这个数是大于等于mid的,否者是小于mid的。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
struct OPT { int opt, a, b; } Q[N];
int a[N], b[N], n, m, k; struct SegmentTree{
int sum[N << ], tag[N << ];
void pushdown(int rt,int len) {
sum[rt << ] = tag[rt] * (len - (len >> )), tag[rt << ] = tag[rt];
sum[rt << | ] = tag[rt] * (len >> ), tag[rt << | ] = tag[rt];
tag[rt] = -;
}
void build(int l,int r,int rt) {
tag[rt] = -;
if (l == r) { sum[rt] = b[l]; return ; }
int mid = (l + r) >> ;
build(l, mid, rt << ); build(mid + , r, rt << | );
sum[rt] = sum[rt << ] + sum[rt << | ];
}
void update(int l,int r,int rt,int L,int R,int v) {
if (L > R) return ;
if (L <= l && r <= R) { tag[rt] = v, sum[rt] = v * (r - l + ); return ; }
if (tag[rt] != -) pushdown(rt, r - l + );
int mid = (l + r) >> ;
if (L <= mid) update(l, mid, rt << , L, R, v);
if (R > mid) update(mid + , r, rt << | , L, R, v);
sum[rt] = sum[rt << ] + sum[rt << | ];
}
int query(int l,int r,int rt,int L,int R) {
if (L <= l && r <= R) return sum[rt];
if (tag[rt] != -) pushdown(rt, r - l + );
int mid = (l + r) >> , res = ;
if (L <= mid) res = query(l, mid, rt << , L, R);
if (R > mid) res += query(mid + , r, rt << | , L, R);
return res;
}
}T; bool check(int x) {
for (int i = ; i <= n; ++i) b[i] = a[i] >= x;
T.build(, n, );
for (int i = ; i <= m; ++i) {
int cnt = T.query(, n, , Q[i].a, Q[i].b);
if (Q[i].opt) {
T.update(, n, , Q[i].a, Q[i].a + cnt - , );
T.update(, n, , Q[i].a + cnt, Q[i].b, );
} else {
T.update(, n, , Q[i].a, Q[i].b - cnt, );
T.update(, n, , Q[i].b - cnt + , Q[i].b, );
}
}
return T.query(, n, , k, k);
} int main() {
n = read(), m = read();
for (int i = ; i <= n; ++i) a[i] = read();
for (int i = ; i <= m; ++i)
Q[i].opt = read(), Q[i].a = read(), Q[i].b = read();
k = read();
int l = , r = n, ans = ;
while (l <= r) {
int mid = (l + r) >> ;
if (check(mid)) ans = mid, l = mid + ;
else r = mid - ;
}
cout << ans << "\n";
return ;
}

4552: [Tjoi2016&Heoi2016]排序的更多相关文章

  1. BZOJ 4552: [Tjoi2016&Heoi2016]排序

    4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 579  Solved: 322[Sub ...

  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]排序 线段树的分裂和合并

    https://www.lydsy.com/JudgeOnline/problem.php?id=4552 https://blog.csdn.net/zawedx/article/details/5 ...

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

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

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

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

  6. BZOJ 4552: [Tjoi2016&Heoi2016]排序 线段树 二分

    目录 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 update 10.6 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 /* //fang zhi ...

  7. bzoj 4552: [Tjoi2016&Heoi2016]排序——二分+线段树

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

  8. bzoj 4552: [Tjoi2016&Heoi2016]排序【二分+线段树】

    二分值mid,然后把>=mid的赋值为1,其他赋值为0,每次排序就是算出区间内01的个数,然后分别把0和1放到连续的一段内,这些都可以用线段树来维护 二分的判断条件是操作完之后q位置上是否为1 ...

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

    听说是BC原题. 好题,二分答案变成01序列,就可以方便的用线段树维护了. 然后就是区间查询和覆盖了. #include <map> #include <cmath> #inc ...

随机推荐

  1. Windows自带强大的入侵检测工具——Netstat 命令 查询是否中木马

    Netstat命令可以帮助我们了解网络的整体使用情况.根据Netstat后面参数的不同,它可以显示不同的网络连接信息.Netstat的参数如图,下面对其中一些参数进行说明.如何检测本机是否有被中木马, ...

  2. 我用的是python2,以后加python3的内容

    可能有的不成功,比如print 'abc',这时候确定下python版本,3的方式是print('abc')

  3. Linux wget命令详解

    wget是一个下载文件的工具,它用在命令行下.对于Linux用户是必不可少的工具,我们经常要下载一些软件或从远程服务器恢复备份到本地服务器. wget支持HTTP,HTTPS和FTP协议,可以使用HT ...

  4. print(dir(...)) 打印对象或者类中的方法和函数

  5. 【Java 笔记】 java 格式化输出

    public static void main(String[] args) { /** * 格式化形式 * %[argument_index$][flags][width][.precision]c ...

  6. Java 替换空格

    题目描述 请实现一个函数,将一个字符串中的空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 解一: 由于最近在学习Head F ...

  7. gitlab+jenkins环境搭建.md

    gitlab+jenkins自动化部署环境搭建 环境说明 系统 主机 IP 安装软件 CentOS 7 study-1 192.168.100.51 gitlab.git CentOS 7 study ...

  8. mybatis #{}和${}的区别是什么

    #{}和${}的区别是什么?正确的答案是:#{}是预编译处理,${}是字符串替换.(1)mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法 ...

  9. python统计磁盘使用情况

    #coding:utf-8import os; def SortList(item):    return item[1]; def ReadSize(fileName):    return flo ...

  10. logstash.conf 根据不同地址创建索引

    input { http { host => "0.0.0.0" port => 9700 type => "from_ys" }}input ...