Brief Description

DZY有一个数列a[1..n],它是1∼n这n个正整数的一个排列。

现在他想支持两种操作:

0, l, r: 将a[l..r]原地升序排序。

1, l, r: 将a[l..r]原地降序排序。

操作完后,他会给你指定一个位置k,请你告诉他a[k]的值。

Algorithm Design

很好的一道题目, 反正我没有想到正解, 但是直接抄袭jcvb的bc题目就不太资辞了(连样例都抄也太懒了吧喂) , 附上原题地址.

这是一道良心的基础数据结构题。

我们二分a[k]的值,假设当前是mid,然后把大于mid的数字标为1,不大于mid的数字标为0。然后对所有操作做完以后检查一下a[k]位置上是0还是1。

因为只有两种值,所以操作还是不难做的。只要用一个线段树,支持区间求和、区间赋值即可。这样要排序一个区间时只要查询一下里面有几个1和几个0,然后把前半段赋值为0,后半段赋值为1即可(降序的话就是反过来)。

复杂度是\(O(mlog^2n)\)的。

这题用其他玄学做法或者用更加厉害的平衡树做法也是有可能AC的。

题解来自jcvb的官方题解

Code

#include <cstdio>
#define init int l = t[k].l, r = t[k].r, mid = (l + r) >> 1
const int maxn = 1e5 + 1e2;
int n, m, a[maxn], lambda, q;
struct seg {
int l, r, val, cov;
} t[maxn << 4];
struct op {
int a, b, c;
} o[maxn];
void update(int k) { t[k].val = t[k << 1].val + t[k << 1 | 1].val; }
void build(int k, int l, int r) {
t[k].l = l, t[k].r = r, t[k].cov = -1;
if (l == r) {
t[k].val = a[l] > lambda;
return;
}
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
update(k);
}
void pushdown(int k) {
if (t[k].cov != -1) {
t[k << 1].cov = t[k].cov;
t[k << 1 | 1].cov = t[k].cov;
t[k << 1].val = (t[k << 1].r - t[k << 1].l + 1) * (t[k].cov);
t[k << 1 | 1].val = (t[k << 1 | 1].r - t[k << 1 | 1].l + 1) * (t[k].cov);
t[k].cov = -1;
}
if (t[k].l < t[k].r)
update(k);
}
int query(int k, int x, int y) {
init;
pushdown(k);
if (x <= l && r <= y)
return t[k].val;
int ans = 0;
if (x <= mid)
ans += query(k << 1, x, y);
if (y > mid)
ans += query(k << 1 | 1, x, y);
return ans;
}
void modify(int k, int x, int y, int val) {
init;
pushdown(k);
if (x <= l && r <= y) {
t[k].val = (r - l + 1) * val;
t[k].cov = val;
return;
}
if (x <= mid)
modify(k << 1, x, y, val);
if (y > mid)
modify(k << 1 | 1, x, y, val);
update(k);
}
bool check(int x) {
lambda = x;
build(1, 1, n);
for (int i = 1; i <= m; i++) {
int opt = o[i].a, x = o[i].b, y = o[i].c;
int tmp = query(1, x, y);
if (opt == 0) {
modify(1, x, y - tmp, 0);
modify(1, y - tmp + 1, y, 1);
} else {
modify(1, x, x + tmp - 1, 1);
modify(1, x + tmp, y, 0);
}
}
return !query(1, q, q);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input", "r", stdin);
#endif
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
int l = 1, r = n;
for (int i = 1; i <= m; i++) {
scanf("%d %d %d", &o[i].a, &o[i].b, &o[i].c);
}
scanf("%d", &q);
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
printf("%d", r);
}

[bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树的更多相关文章

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

    [BZOJ4552][Tjoi2016&Heoi2016]排序 Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ...

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

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

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

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

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

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

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

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

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

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

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

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

  8. BZOJ4552 Tjoi2016&Heoi2016排序 【二分+线段树】*

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

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

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

随机推荐

  1. As a Start - 毫厘之间,宇宙之外

    序 突然想聊聊多重宇宙——多重宇宙,这听上去像是一个科幻概念,但是严肃思考这一个问题时,将会带我们进入一个全新的格局和世界. 对宇宙学家而言,研究多重宇宙并不仅仅是为了猜测平行世界里某一历史事件是否有 ...

  2. CC2650LaunchPad 运行contiki hello-world示例程序

    最近做毕设,开始接触contiki. 下载并运行Instant Contiki 3.0 这是官方制作的虚拟机镜像,直接用vmware等工具就可以运行. 从这里下载. 下载并解压后,用vmware运行. ...

  3. mybatis_SQL映射(3)

    文章摘录自:http://blog.csdn.net/y172158950/article/details/17304645 1. 表关联 a) 嵌套查询(传说中的1+N问题) <resultM ...

  4. mysql插入数据后返回自增ID的方法,last_insert_id(),selectkey

    mysql插入数据后返回自增ID的方法 mysql和oracle插入的时候有一个很大的区别是,oracle支持序列做id,mysql本身有一个列可以做自增长字段,mysql在插入一条数据后,如何能获得 ...

  5. java基础学习总结——java读取properties文件总结

    摘录自:http://www.cnblogs.com/xdp-gacl/p/3640211.html 一.java读取properties文件总结 在java项目中,操作properties文件是经常 ...

  6. ASP.NET导出word实例

    ASP.NET导出word实例 最近遇到一个题目就是如何在asp.net中将数据导出到word中,由于数据是动态的,所以需要在后台拼出想要的的格式,翻遍了网页找出了一个比较满意的代码,感谢那位高手.代 ...

  7. 深入浅出docker

    笔者在海外工作多年,所以文中多用英文单词,有些时候是为了更精准的描述,请见谅.希望这篇随笔能帮大家入门docker.由于在海外连博客园有些慢,所以我图片用的比较少,以后再考虑一下如何更好的解决图片上传 ...

  8. Java多线程之线程的通信

    Java多线程之线程的通信 在总结多线程通信前先介绍一个概念:锁池.线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池.每个对象都有自己的锁池的空间,用于放置等待运行的线程.这些 ...

  9. mysql数据库表字段使用DESC等关键字报错及解决方法

    <!-- desc是MySQL数据库的关键字,作为字段名直接使用会报错 --><sql id="Base_Column"> id,mol,ip,port,n ...

  10. 【转】IGS相关

    目 前,全球260多个lGS跟踪站中,我国占20多个,分布在武汉.拉萨.乌鲁木齐.昆明.上海等地,全球IGS网的GPS数据,由单台接收机交换 (RINEX)格式生成的日观测和导航数据文件组成,其存储方 ...