题解【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], ...
随机推荐
- Java程序设计基础项目总结报告
Java程序设计基础项目总结报告 20135313吴子怡 一.项目内容 运用所学Java知识,不调用Java类库,实现密码学相关算法的设计,并完成TDD测试,设计运行界面. 二.具体任务 1.要求实现 ...
- 关于如何使用Microsoft Word发博客
关于如何使用Microsoft Word发博客 PS:以Microsoft Word 2010为例作具体操作,实际上Microsoft Word 2007也可以完成该功能,略有差异,但是只能是20 ...
- YQCB冲刺第二周第二天
今天的任务依然为实现查看消费明细的功能. 遇到的问题为从数据库中分类读取,实现图标的显示. 站立会议为: 任务面板为:
- 《JavaScript》forEach()和map()
js中的forEach()方法只能遍历数组,不能遍历字符串和对象,和$.each()有很多使用上的区别array.forEach(funcion(value,index,arr){},thisValu ...
- 再学HTML之一
Html 超文本标记语言 什么是html? HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言, ...
- Codeforces Round #106 (Div. 2) D. Coloring Brackets 区间dp
题目链接: http://codeforces.com/problemset/problem/149/D D. Coloring Brackets time limit per test2 secon ...
- 树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 (一) 配置与测试
引脚连接说明 与树莓派的连线 NRF24L01 => 树莓派 GND => GND VCC => 3.3V CE = ...
- H5页面的滚动条在windows浏览器下始终看到(灰色的不可用的)
一般这种情况是在某些相关的div上设置了overflow:scroll属性,在mac系统的浏览器下均没有滚动条显示而在windows下的各个浏览器上均可以看到灰色的不可用的滚动条,这种情况我们需要在b ...
- 0523 Scrum项目6.0
0523 团队项目6.0 一,组员任务完成情况 首页设计初步完成但是需要优化界面,只能简单的输出信息和在首页进行登录.界面极其简单.使用了Javabean的设计模式,进行改进,使得页面的里的代码看起来 ...
- Alpha阶段事后诸葛分析
一.设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件主要是解决在宿舍中购买商品的软件,不同于淘宝等软件,本软件主要是用于学生开设的店铺及宿 ...