BZOJ 4552: [Tjoi2016&Heoi2016]排序
4552: [Tjoi2016&Heoi2016]排序
Time Limit: 60 Sec Memory Limit: 256 MB
Submit: 579 Solved: 322
[Submit][Status][Discuss]
Description
Input
Output
输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第q位置上的数字。
Sample Input
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
Sample Output
HINT
Source
首先二分答案,然后需要知道进行m次排序后p位置上的数字是否大于mid。
对于一个mid,我们可以把序列里的数字分为两类,即大于mid的数和小于等于mid的数,分别用1和0表示。
对这些0和1进行排序时,对于一个区间[l,r]进行升序排序,等价于把所有的0放在前面,所有的1放在后面;降序排序反之。
用线段树支持区间求和及区间修改即可。
#include <bits/stdc++.h> #define fread_siz 1024 inline int get_c(void)
{
static char buf[fread_siz];
static char *head = buf + fread_siz;
static char *tail = buf + fread_siz; if (head == tail)
fread(head = buf, , fread_siz, stdin); return *head++;
} inline int get_i(void)
{
register int ret = ;
register int neg = false;
register int bit = get_c(); for (; bit < ; bit = get_c())
if (bit == '-')neg ^= true; for (; bit > ; bit = get_c())
ret = ret * + bit - ; return neg ? -ret : ret;
} const int maxn = 1e5 + ; int n, m;
int total;
int num[maxn];
int map[maxn]; struct Query
{
int k, l, r;
}qry[maxn]; int pos; struct Node
{
int sum;
int tag;
int lt, rt;
}tree[maxn << ]; #define lson(t) (t << 1)
#define rson(r) (t << 1 | 1) void build(int t, int l, int r, int k)
{
tree[t].lt = l;
tree[t].rt = r;
tree[t].tag = -; if (l == r)
tree[t].sum = num[l] > k;
else
{
int mid = (l + r) >> ;
build(lson(t), l, mid, k);
build(rson(t), mid + , r, k);
tree[t].sum = tree[lson(t)].sum + tree[rson(t)].sum;
}
} void change(int t, int l, int r, int k)
{
if (l > r)return; if (l == tree[t].lt && r == tree[t].rt)
tree[t].sum = (r - l + ) * k, tree[t].tag = k;
else
{
int mid = (tree[t].lt + tree[t].rt) >> ; if (tree[t].tag != -)
{
change(lson(t), tree[t].lt, mid, tree[t].tag);
change(rson(t), mid + , tree[t].rt, tree[t].tag);
tree[t].tag = -;
} if (r <= mid)
change(lson(t), l, r, k);
else if (l > mid)
change(rson(t), l, r, k);
else
change(lson(t), l, mid, k), change(rson(t), mid + , r, k); tree[t].sum = tree[lson(t)].sum + tree[rson(t)].sum;
}
} int query(int t, int l, int r)
{
if (l == tree[t].lt && r == tree[t].rt)
return tree[t].sum; int mid = (tree[t].lt + tree[t].rt) >> ; if (tree[t].tag != -)
{
change(lson(t), tree[t].lt, mid, tree[t].tag);
change(rson(t), mid + , tree[t].rt, tree[t].tag);
tree[t].tag = -;
} if (r <= mid)
return query(lson(t), l, r);
else if (l > mid)
return query(rson(t), l, r);
else
return query(lson(t), l, mid) + query(rson(t), mid + , r);
} inline bool check(int mid)
{
build(, , n, mid); for (int i = ; i <= m; ++i)
{
int q = query(, qry[i].l, qry[i].r); if (qry[i].k)
{
change(, qry[i].l, qry[i].l + q - , );
change(, qry[i].l + q, qry[i].r, );
}
else
{
change(, qry[i].l, qry[i].r - q, );
change(, qry[i].r - q + , qry[i].r, );
}
} return query(, pos, pos);
} signed main(void)
{
n = get_i();
m = get_i(); for (int i = ; i <= n; ++i)
num[i] = get_i(); for (int i = ; i <= m; ++i)
{
qry[i].k = get_i();
qry[i].l = get_i();
qry[i].r = get_i();
} pos = get_i(); memcpy(map, num, sizeof(map));
std::sort(map + , map + + n);
total = std::unique(map + , map + + n) - map; int lt = , rt = total, mid, ans; while (lt <= rt)
{
if (check(mid = (lt + rt) >> ))
lt = mid + ;
else
rt = mid - , ans = mid;
} printf("%d\n", map[ans]);
}
@Author: YouSiki
BZOJ 4552: [Tjoi2016&Heoi2016]排序的更多相关文章
- bzoj 4552 [Tjoi2016&Heoi2016]排序 (二分答案 线段树)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 题意: 给你一个1-n的全排列,m次操作,操作由两种:1.将[l,r]升序排序,2 ...
- BZOJ 4552 [Tjoi2016&Heoi2016]排序 线段树的分裂和合并
https://www.lydsy.com/JudgeOnline/problem.php?id=4552 https://blog.csdn.net/zawedx/article/details/5 ...
- bzoj 4552 [Tjoi2016&Heoi2016]排序——二分答案
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案,把 >= mid 的设成1.< mid 的设成0,之后排序就变成 ...
- BZOJ 4552 [Tjoi2016&Heoi2016]排序 | 二分答案 线段树
题目链接 题面 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- BZOJ 4552: [Tjoi2016&Heoi2016]排序 线段树 二分
目录 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 update 10.6 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 /* //fang zhi ...
- bzoj 4552: [Tjoi2016&Heoi2016]排序——二分+线段树
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- bzoj 4552: [Tjoi2016&Heoi2016]排序【二分+线段树】
二分值mid,然后把>=mid的赋值为1,其他赋值为0,每次排序就是算出区间内01的个数,然后分别把0和1放到连续的一段内,这些都可以用线段树来维护 二分的判断条件是操作完之后q位置上是否为1 ...
- BZOJ 4552 [Tjoi2016&Heoi2016]排序 ——线段树 二分答案
听说是BC原题. 好题,二分答案变成01序列,就可以方便的用线段树维护了. 然后就是区间查询和覆盖了. #include <map> #include <cmath> #inc ...
- 4552: [Tjoi2016&Heoi2016]排序
4552: [Tjoi2016&Heoi2016]排序 链接 分析: 因为只询问一次,所以考虑二分这个数.显然是没有单调性的,但是我们可以二分所有大于等于mid的数中,是否有满足条件的x(而不 ...
随机推荐
- Cucumber测试驱动开发
Cucumber是一种BDD实践开发工具,属于敏捷开发的组成部分. 在敏捷开发中,对用户进行需求分析时,不是像传统的P&D的开发方式,首先编写大量的用户需求分析文档,而是通过一个个 ...
- C# CompareTo 和 String.Compare
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 重装win7、vs15、sqlserver08、驱动经验教训
问自己:为什么要进行系统清洗 1.C盘已经接近爆满,vs2015无法安装. 2.C盘以前的残留软件.文件不知道如何化解,原vs2010卸载困难. 3.整个系统反应迟缓. 改进方案: 1系统C盘 2软件 ...
- Linux笔记:使用Vim编辑器
Vi编辑器是Unix系统上早先的编辑器,在GNU项目将Vi编辑器移植到开源世界时,他们决定对其作一些改进. 于它不再是以前Unix中的那个原始的Vi编辑器了,开发人员也就将它重命名为Vi improv ...
- js中的prototype和__proto__
var Person = function(name){ this.name = name; this.say = function(){ return "I am " + thi ...
- #ifndef _LED_H #endif啥意思?
#ifndef _LED_H#ifndef _LED_H ...... ...... #endif 避免重复引用头文件的内容.
- git 常规使用小结
总结下 git 的常规使用: 一般我们使用 git 来维护项目代码. 前提背景: 远程服务器上代码库,包含分支: 1.master - 版本发布分支 2.dev - 平时开发用的分支 一般操作流程: ...
- 第一轮复习完毕,kmp走起
//代码via:http://blog.csdn.net/v_JULY_v/article/details/6111565 //简单思路via:http://study.163.com/course/ ...
- 基于网格的分割线优化算法(Level Set)
本文介绍一种网格分割线的优化算法,该方法能够找到网格上更精确.更光滑的分割位置,并且分割线能够自由地合并和分裂,下面介绍算法的具体原理和过程. 曲面上的曲线可以由水平集(level set)形式表示, ...
- UNIX系统基本结构
UNIX系统的基本结构如图所示.整个UNIX系统可分为五层:最底层是裸机,即硬件部分:第二层是UNIX的核心,它直接建立在裸机的上面,实现了操作系统重要的功能,如进程管理.存储管理.设备管理.文件管理 ...