题解【bzoj2653 middle】
Description
给你一个序列,每次询问给出四个数 \(a,b,c,d\),求所有区间 \([l,r]\) 满足 \(l \in [a,b], r \in [c,d]\) 的中位数的最大值。强制在线
\(n \leq 20000, Q \leq 25000,a_i \leq 10^9\)
Solution
考虑二分答案。假设现在二分出来的是 \(x\) ,那么把 \(\ge x\) 的位置设成 \(1\) ,\(< x\) 的设为 \(-1\) 。那么一个区间的中位数 \(\ge x\) 等价于这个区间的和 \(\ge 0\)
如何处理题目给的左右端点的限制?
可以发现 \([l,r]\) 必然包含 \([b+1,c-1]\) (如果 \(b+1 \leq c+1\) 的话)所以 \([l, r]\) 的和必然包含 \([b+1, c-1]\) 的和
显然让 \([l,r]\) 的和最大的方案是取 \([a,b]\) 的最大右段和 和 \([c,d]\) 的最大左段和
这些都可以用线段树维护。但这样需要每个数都开一颗线段树,空间爆炸。
把数组排序,这样每个数的线段树显然只是由前一个数的线段树把一个点的权值从 \(1\) 改为 \(-1\) 。可以使用主席树的思想(貌似就是主席树
然后就做完了。复杂度 \(O(m \log^2 n)\)
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 2000;
int n, m; int q[4];
struct Node {
int d, id;
} a[N];
inline bool cmp(Node x, Node y) {
return x.d < y.d;
}
struct node {
int left, right;
int sm, lm, rm;
node *ch[2];
inline void upd() {
sm = ch[0]->sm + ch[1]->sm;
lm = max(ch[0]->lm, ch[0]->sm + ch[1]->lm);
rm = max(ch[1]->rm, ch[1]->sm + ch[0]->rm);
}
} *rt[N], pool[N * 50], *cur = pool, *ans;
inline void B (node *r, int left, int right) {
r->left = left, r->right = right;
if(left == right) { r->sm = r->lm = r->rm = 1; return ; }
node *lson = cur++, *rson = cur++;
int mid = (left + right) >> 1;
r->ch[0] = lson, r->ch[1] = rson;
B(lson, left, mid), B(rson, mid + 1, right); r->upd();
}
inline void I (node *pre, node *now, int pos) {
now->left = pre->left, now->right = pre->right;
if(now->left == now->right) {
now->sm = now->lm = now->rm = -1; return ;
} int mid = (pre->left + pre->right) >> 1;
if(pos <= mid) now->ch[1] = pre->ch[1], I(pre->ch[0], now->ch[0] = cur++, pos);
if(pos > mid) now->ch[0] = pre->ch[0], I(pre->ch[1], now->ch[1] = cur++, pos);
now->upd();
}
inline node* Q (node *now, int l, int r) {
if(now->left == l && now->right == r) return now;
if(now->ch[0]->right >= r) return Q(now->ch[0], l, r);
else if(now->ch[1]->left <= l) return Q(now->ch[1], l, r);
else {
node *ret = cur++, *L, *R;
L = Q(now->ch[0], l, now->ch[0]->right);
R = Q(now->ch[1], now->ch[1]->left, r);
ret->sm = L->sm + R->sm;
ret->lm = max(L->lm, L->sm + R->lm);
ret->rm = max(R->rm, R->sm + L->rm);
return ret;
}
}
inline bool check(int id) {
int sum = 0;
if(q[2] + 1 <= q[3] - 1) sum += Q (rt[id - 1], q[2] + 1, q[3] - 1)->sm;
sum += Q (rt[id - 1], q[1], q[2])->rm;
sum += Q (rt[id - 1], q[3], q[4])->lm;
return sum >= 0;
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i].d);
a[i].id = i;
} sort(a + 1, a + n + 1, cmp);
B(rt[0] = cur++, 1, n);
for(int i = 1; i <= n; i++) {
rt[i] = cur++; I(rt[i - 1], rt[i], a[i].id);
}
int ans = 0; scanf("%d", &m);
for(int i = 1; i <= m; i++) {
for(int j = 1; j <= 4; j++) {
scanf("%d", &q[j]),
q[j] += ans, q[j] %= n; q[j]++;
}
sort(q + 1, q + 4 + 1);
int l = 1, r = n;
while(l <= r) {
int mid = (l + r) / 2;
if(check(mid)) l = mid + 1, ans = a[mid].d;
else r = mid - 1;
} printf("%d\n", ans);
}
return 0;
}
题解【bzoj2653 middle】的更多相关文章
- BZOJ2653 middle 【主席树】【二分】*
BZOJ2653 middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个长度为n的序列s.回答Q个这样 ...
- bzoj2653: middle
首先,对于每个询问,我们二分答案 然后对于序列中大于等于中位数的数,我们把它们置为1,小于中位数的数,置为-1 那么如果一个区间和大于等于0,那么就资磁,否则就不滋磁 这个区间和呢,我们可以用主席树维 ...
- BZOJ2653 middle(二分答案+主席树)
与中位数有关的题二分答案是很常用的trick.二分答案之后,将所有大于它的看成1小于它的看成-1,那么只需要判断是否存在满足要求的一段和不小于0. 由于每个位置是1还是-1并不固定,似乎不是很好算.考 ...
- [BZOJ2653]middle 主席树+二分
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2042 Solved: 1123[Submit][Status][Disc ...
- BZOJ2653 middle 【二分 + 主席树】
题目 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c ...
- [bzoj2653][middle] (二分 + 主席树)
Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b ...
- PKUSC2018训练日程(4.18~5.30)
(总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...
- 算法与数据结构基础 - 链表(Linked List)
链表基础 链表(Linked List)相比数组(Array),物理存储上非连续.不支持O(1)时间按索引存取:但链表也有其优点,灵活的内存管理.允许在链表任意位置上插入和删除节点.单向链表结构一般如 ...
- BZOJ2653:middle——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2653 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2], ...
随机推荐
- 分布式高并发下全局ID生成策略
数据在分片时,典型的是分库分表,就有一个全局ID生成的问题.单纯的生成全局ID并不是什么难题,但是生成的ID通常要满足分片的一些要求: 1 不能有单点故障. 2 以时间为序,或者ID里包含时间 ...
- 苹果针对on sale 的APP发的问题邮件
2017年3月8日 上午8:07 发件人 Apple Dear Developer, Your app, extension, and/or linked framework appears to c ...
- centos 切换用户显示bash-4.2$,不显示用户名路径的问题
原文链接: http://blog.csdn.net/testcs_dn/article/details/70482468
- [BUAA软工]第零次博客作业---问题回答
[BUAA软工]第0次博客作业 项目 内容 这个作业属于哪个课程 北航软工 这个作业的要求在哪里 第0次个人作业 我在这个课程的目标是 学习如何以团队的形式开发软件,提升个人软件开发能力 这个作业在哪 ...
- Task 6.4 冲刺Two之站立会议5
在完成主界面和聊天窗口的连接之后,今天对聊天界面在以前的基础上添加了很多东西,比如说对于文件传输和文字通信时的表情包的添加以及抖动窗口的设置等等一一系列的功能.我完成的是文字通信这一部分的内容.
- 关于地图首页会卡 button background惹的祸
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:sat=&q ...
- 超实用 1 ArrayList 链表
package ArrayList链表; import java.util.*; public class kk1 { /** * 作者:Mr.Fan * 功能:记住ArrayList链表 */ pu ...
- 转 js事件探秘
Javascript中的事件,可以和html交互. 事件流IE&Opera:事件冒泡其他浏览器: 事件捕获 事件冒泡:事件由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至 ...
- Log4j读取配置文件并使用
/** 设置配置路径从环境变量读取 * PropertyConfigurator类加载.properties文件的配置 * DOMConfigurator加载.xml文件的配置 ...
- js遍历数组和遍历对象
可以用for in来遍历对象,具体内容如下: <script type="text/javascript"> var objs = { ...