P2839 [国家集训队]middle

有一个长度为nnn的序列,有mmm次询问,每次询问a,b,c,da, b, c, da,b,c,d,为l∈[a,b],r∈[c,d]l \in [a, b], r \in [c, d]l∈[a,b],r∈[c,d],[l,r][l, r][l,r]区间的中位数最大是多少,强制在线,1≤n≤20000,1≤m≤250001 \leq n \leq 20000, 1 \leq m \leq 250001≤n≤20000,1≤m≤25000。

由于有a≤b≤c≤da \leq b \leq c \leq da≤b≤c≤d,分三个区间讨论[a,b],[b+1,c−1],[c,d][a, b], [b + 1, c - 1], [c, d][a,b],[b+1,c−1],[c,d],其中[b+1,c−1][b + 1, c - 1][b+1,c−1]这个区间是必选的,[a,b],[c,d][a, b], [c, d][a,b],[c,d]这俩个区间可选可不选,

我们考虑二分答案,对于mid≤aimid \leq a_imid≤ai​的我们设置为111,否则我们设置为−1-1−1,对于选定的区间,如果中位数是等于midmidmid的,则一定有区间和>=0>= 0>=0,

由于我们要使区间中位数尽可能地大,所以我们定然是在[a,b][a, b][a,b]上选一个点ppp在1,−11, -11,−1序列上使得[p,b][p, b][p,b]的和最大,在[c,d][c, d][c,d]上选定一个点qqq也是如此。

如此做的话,单次询问复杂度将会是O(nlog⁡nlog⁡n)O(n \log n \log n )O(nlognlogn)的,有没有办法高效来完成呢,整体二分似乎是一个比较好的方法,但是这题要求在线求解,,,

整理一下上面我们所需要的值,[b+1,c−1][b + 1, c - 1][b+1,c−1]的区间和,[a,b][a, b][a,b]区间的后缀最大值,[c,d][c, d][c,d]区间的前缀最大值,

对于任意一个区间的后缀最大值,前缀最大值都可用线段树维护,同样的区间和也可以用线段树维护,

目前我们所需的就是对于任何一个midmidmid,我们要精确地知道对于某段区间地前缀最大,前缀最小,区间和,

这里就可以考虑用主席树,对每个二分地midmidmid都建立一颗主席树,对于每次二分地midmidmid是否合法,我们只要到对应地主席树上查找即可。

#include <bits/stdc++.h>using namespace std;const int N = 2e4 + 10;struct Seg {int l, r, sum;
}t[N << 6];int root[N], ls[N << 6], rs[N << 6], num;int a[N], b[N], n, m;Seg operator + (Seg a, Seg b) {Seg ans;ans.sum = a.sum + b.sum;ans.l = max(a.l, a.sum + b.l);ans.r = max(b.r, b.sum + a.r);return ans;
}void push_up(int rt) {t[rt] = t[ls[rt]] + t[rs[rt]];
}void build(int &rt, int l, int r) {rt = ++num;if (l == r) {t[rt] = {-1, -1, -1};return ;}int mid = l + r >> 1;build(ls[rt], l, mid);build(rs[rt], mid + 1, r);push_up(rt);
}void update(int &rt, int pre, int l, int r, int x) {rt = ++num, ls[rt] = ls[pre], rs[rt] = rs[pre];if (l == r) {t[rt] = {1, 1, 1};return ;}int mid = l + r >> 1;if (x <= mid) {update(ls[rt], ls[pre], l, mid, x);}else {update(rs[rt], rs[pre], mid + 1, r, x);}push_up(rt);
}Seg query(int rt, int l, int r, int L, int R) {if (l >= L && r <= R) {return t[rt];}int mid = l + r >> 1;if (L <= mid && R > mid) {return query(ls[rt], l, mid, L, R) + query(rs[rt], mid + 1, r, L, R);}else if (L <= mid) {return query(ls[rt], l, mid, L, R);}else {return query(rs[rt], mid + 1, r, L, R);}
}int aa, bb, cc, dd;bool judge(int x) {int res = 0;res += query(root[x], 1, n, aa, bb).r;if (bb + 1 <= cc - 1) {res += query(root[x], 1, n, bb + 1, cc - 1).sum;}res += query(root[x], 1, n, cc, dd).l;return res >= 0;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);b[i] = i;}scanf("%d", &m);build(root[n + 1], 1, n);sort(b + 1, b + 1 + n, [&] (int x, int y) {return a[x] < a[y];});for (int i = n; i >= 1; i--) {update(root[i], root[i + 1], 1, n, b[i]);}int ans = 0;for (int i = 1; i <= m; i++) {scanf("%d %d %d %d", &aa, &bb, &cc, &dd);aa = (aa + ans) % n + 1, bb = (bb + ans) % n + 1;cc = (cc + ans) % n + 1, dd = (dd + ans) % n + 1;int tmp[5] = {0, aa, bb, cc, dd};sort(tmp + 1, tmp + 4 + 1);aa = tmp[1], bb = tmp[2], cc = tmp[3], dd = tmp[4];int l = 1, r = n;while (l < r) {int mid = l + r + 1 >> 1;if (judge(mid)) {l = mid;}else {r = mid - 1;}}ans = a[b[l]];printf("%d\n", ans);}return 0;
}

P2839 [国家集训队]middle(二分 套 主席树)相关推荐

  1. P2839 [国家集训队]middle 二分 + 主席树 在值域上建区间

    传送门 文章目录 题意: 思路: 题意: 思路: 我们先解决怎么判断中位数的问题,我们可以二分一个midmidmid,将<mid<mid<mid的值都变成−1-1−1,其他的数都变成 ...

  2. 洛谷P2839 [国家集训队]middle(主席树)

    P2839 [国家集训队]middle 我们可以考虑二分中位数 checkcheckcheck 答案,那么我们对于某个值 midmidmid ,把 [l,r][l,r][l,r] 内的所有小于 mid ...

  3. bzoj 2653 洛谷 P2839 [国家集训队] middle

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 2381  Solved: 1340 [Submit][Status][Di ...

  4. P2839 [国家集训队]middle

    题面 • 提一下静态区间第k小的nlog2n的做法: 1. 建关于排名的主席树(按排名顺序建树). 2. 二分答案. • 这样做静态区间第k小的虽然有些ZZ,但它的意义在于将线段树   维护的对象改变 ...

  5. 可持久化普通线段树 ---- P2839 [国家集训队]middle 可持久化普通线段树 + 二分 求中位数最大值

    题目链接 题目大意: 解题思路: 这个题思路很妙!! 首先我们假设只有一次询问怎么做? 那么我们可以二分出这个最大值midmidmid,然后把大于等于midmidmid设置成111,把小于midmid ...

  6. H - Hello Ms. Ze(树状数组套主席树,线段树上二分)

    H - Hello Ms. Ze 给定nnn种不同的材料,第iii种材料有aia_iai​个,有mmm个操作,操作分为两类: 把第xxx种材料修改为yyy个, 只用[l,r][l, r][l,r]区间 ...

  7. BZOJ1146[CTSC2008]网络管理——出栈入栈序+树状数组套主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条 ...

  8. zoj 2112 树状数组 套主席树 动态求区间 第k个数

    总算是把动态求区间第k个数的算法看明白了. 在主席树的基础上,如果有修改操作,则要通过套树状数组来实现任意区间求第k小的问题. 刚开始看不明白什么意思,现在有一点理解.树状数组的每个元素是一个线段树, ...

  9. ICPC 徐州 H Yuuki and a problem (树状数组套主席树)

    Yuuki and a problem 先不管第一问的修改操作,考虑如何达到第二问的查询操作, 题目要我们给出一个区间[l,r][l, r][l,r]中,不能通过权值+++得到的最小的数字是什么, 假 ...

最新文章

  1. 3D视觉创新应用(三维重建)竞赛作品系列——多楼层室内环境下的三维几何重建
  2. 【原创】rabbitmq-env.conf用户手册(翻译)
  3. AI现在能教你画画了
  4. C++实现链栈的基本操作
  5. SQLite/嵌入式数据库
  6. nRF51822 配对之device_manager_init 调用,以及保证 用户数据存储 的Flash 操作不与device manager 模块冲突...
  7. 信安教程第二版-第17章网络安全应急响应技术原理与应用
  8. 【HNOI2003】【BZOJ1216】操作系统(模拟,优先队列)
  9. Python 清理项目的目录
  10. 去阿里面试被问:如果是MySQL引起的CPU消耗过大,你会如何优化?
  11. paip.从HTML select 获取数据
  12. HTB-oscplike-Bounty+Jerry+Conceal
  13. C语言 16进制与字符串互转函数
  14. 关于一台电脑控制多台手机技术分享被恶意转载的声明
  15. 几款常见的可视化HTML编辑器(WYSIWYG)
  16. html倒计时的原理,JS实现活动精确倒计时 - 轩枫阁
  17. clickhouse的傻瓜式安装和基础入门
  18. modis遥感影像数据批量下载(不限制网速的办法)
  19. winform做的单机登录界面和账号注册界面
  20. 专升本英语——应试题型突破——阅读理解——阅读理解做题技巧【学习笔记】

热门文章

  1. 一杆台球的击球力道竟能传递35米?
  2. 微信新功能又来了,这些功能再次打开了我新世界的大门!
  3. 这几道挑战极限的烧脑题,烧脑到爽爽爽爽爽!
  4. 厉害了!这几位小学生竟然在艺术界掀起一阵风暴,简直是灵魂画手无疑.........
  5. 看完这13张图,不得不佩服还是外国人会玩人工智能
  6. 触发键盘_雷蛇这款光轴机械键盘开箱评测,光速触发,颜值爆表
  7. url采集工具_大数据关键技术浅谈之大数据采集
  8. html怎么快速打出来的,javascript – 快速打印HTML5画布
  9. html的标签和标记有啥区别,HTML 元素 b 和 strong 有什么区别?//(强调标签的理解)...
  10. ajax和spa的区别,在XX团上消费过一次不正规的Spa,现在过来两个月公安局打电话叫我过去...