luogu2839 [国家集训队]middle
题目链接:洛谷
题目大意:给定一个长度为$n$的序列,每次询问左端点在$[a,b]$,右端点在$[c,d]$的所有子区间的中位数的最大值。(强制在线)
这里的中位数定义为,对于一个长度为$n$的序列排序之后为$a_0,a_1,\ldots,a_{n-1}$,则$a_{\lfloor\frac{n}{2}\rfloor}$为这个序列的中位数。
数据范围:$1\leq n\leq 20000$,$1\leq q\leq 25000$,$1\leq a\leq b\leq c\leq d\leq n$
这道题才是真正的主席树!
首先我们考虑离散化,然后二分答案,判断这些区间的中位数是否有可能$\geq mid$,那怎么判断呢?
我们发现,如果把这个序列的所有$\geq mid$的数改为1,$<mid$的数改为$-1$,则上述条件等价于这个新的数列之和非负。(这是一个非常神仙的套路)
所以我们对于所有的数$a_i$,预处理出这个1/-1的序列,但是这样空间会爆炸。
我们发现这些序列中,$a_{i-1}$和$a_i$的序列之间仅有一位不同。
于是主席树闪亮登场。
然后判断一下左端点在$[a,b]$,右端点在$[c,d]$的最大子段和,判断一下是否$\geq 0$。
1 #include<cstdio> 2 #include<algorithm> 3 #define Rint register int 4 using namespace std; 5 const int N = 20003; 6 int n, Q, q[4], lans, a[N], id[N], root[N], ls[N << 5], rs[N << 5], cnt; 7 struct Node { 8 int sum, lmax, rmax; 9 inline Node(int s = 0, int l = 0, int r = 0): sum(s), lmax(l), rmax(r){} 10 inline Node operator + (const Node &o) const { 11 return Node(sum + o.sum, max(lmax, sum + o.lmax), max(o.rmax, o.sum + rmax)); 12 } 13 } seg[N << 5]; 14 inline void pushup(int x){ 15 seg[x] = seg[ls[x]] + seg[rs[x]]; 16 } 17 inline void build(int &x, int L, int R){ 18 x = ++ cnt; 19 if(L == R){ 20 seg[x] = Node(1, 1, 1); 21 return; 22 } 23 int mid = L + R >> 1; 24 build(ls[x], L, mid); 25 build(rs[x], mid + 1, R); 26 pushup(x); 27 } 28 inline void change(int &nx, int ox, int L, int R, int pos){ 29 nx = ++ cnt; 30 ls[nx] = ls[ox]; rs[nx] = rs[ox]; 31 if(L == R){ 32 seg[nx] = Node(-1, -1, -1); 33 return; 34 } 35 int mid = L + R >> 1; 36 if(pos <= mid) change(ls[nx], ls[ox], L, mid, pos); 37 else change(rs[nx], rs[ox], mid + 1, R, pos); 38 pushup(nx); 39 } 40 inline Node query(int x, int L, int R, int l, int r){ 41 if(!x || l > r) return Node(); 42 if(l <= L && R <= r) return seg[x]; 43 int mid = L + R >> 1; 44 if(r <= mid) return query(ls[x], L, mid, l, r); 45 else if(mid < l) return query(rs[x], mid + 1, R, l, r); 46 else return query(ls[x], L, mid, l, r) + query(rs[x], mid + 1, R, l, r); 47 } 48 inline int solve(int a, int b, int c, int d){ 49 int l = 1, r = n, mid, tmp; 50 while(l <= r){ 51 mid = l + r >> 1; 52 tmp = query(root[mid], 1, n, a, b).rmax + query(root[mid], 1, n, b + 1, c - 1).sum + query(root[mid], 1, n, c, d).lmax; 53 if(tmp >= 0) l = mid + 1; 54 else r = mid - 1; 55 } 56 return id[r]; 57 } 58 int main(){ 59 scanf("%d", &n); 60 for(Rint i = 1;i <= n;i ++){ 61 scanf("%d", a + i); id[i] = i; 62 } 63 sort(id + 1, id + n + 1, [](int x, int y) -> bool {return a[x] < a[y];}); 64 build(root[1], 1, n); 65 for(Rint i = 1;i < n;i ++) 66 change(root[i + 1], root[i], 1, n, id[i]); 67 scanf("%d", &Q); 68 while(Q --){ 69 for(Rint i = 0;i < 4;i ++){ 70 scanf("%d", q + i); 71 q[i] = (q[i] + lans) % n + 1; 72 } 73 sort(q, q + 4); 74 printf("%d\n", lans = a[solve(q[0], q[1], q[2], q[3])]); 75 } 76 }
View Code
转载于:https://www.cnblogs.com/AThousandMoons/p/10630747.html
luogu2839 [国家集训队]middle相关推荐
- P2839 [国家集训队]middle(二分 套 主席树)
P2839 [国家集训队]middle 有一个长度为nnn的序列,有mmm次询问,每次询问a,b,c,da, b, c, da,b,c,d,为l∈[a,b],r∈[c,d]l \in [a, b], ...
- 洛谷P2839 [国家集训队]middle(主席树)
P2839 [国家集训队]middle 我们可以考虑二分中位数 checkcheckcheck 答案,那么我们对于某个值 midmidmid ,把 [l,r][l,r][l,r] 内的所有小于 mid ...
- bzoj 2653 洛谷 P2839 [国家集训队] middle
2653: middle Time Limit: 20 Sec Memory Limit: 512 MB Submit: 2381 Solved: 1340 [Submit][Status][Di ...
- 可持久化普通线段树 ---- P2839 [国家集训队]middle 可持久化普通线段树 + 二分 求中位数最大值
题目链接 题目大意: 解题思路: 这个题思路很妙!! 首先我们假设只有一次询问怎么做? 那么我们可以二分出这个最大值midmidmid,然后把大于等于midmidmid设置成111,把小于midmid ...
- [bzoj 2653][国家集训队]middle
传送门 Description 一个长度为\(n\)的序列\(a\),设其排过序之后为\(b\),其中位数定义为\(b[n/2]\),其中\(a,b\)从\(0\)开始标号,除法取下整. 给你一个长度 ...
- P2839 [国家集训队]middle
题面 • 提一下静态区间第k小的nlog2n的做法: 1. 建关于排名的主席树(按排名顺序建树). 2. 二分答案. • 这样做静态区间第k小的虽然有些ZZ,但它的意义在于将线段树 维护的对象改变 ...
- P2839 [国家集训队]middle 二分 + 主席树 在值域上建区间
传送门 文章目录 题意: 思路: 题意: 思路: 我们先解决怎么判断中位数的问题,我们可以二分一个midmidmid,将<mid<mid<mid的值都变成−1-1−1,其他的数都变成 ...
- [国家集训队]middle(二分+主席树[中位数思维题])
文章目录 点击查看 solution code 点击查看 solution 简单口胡一下就跑 考虑二分答案ansansans 区间[x1,x2],x1∈[a,b],x2∈[c,d][x1,x2],x1 ...
- [国家集训队]middle
嘟嘟嘟 有谁能想到这题会用到主席树呢?(不愧是WJMZBMR出的题) 首先考虑如果区间是固定的话,中位数该怎么求. 没错,二分.如果大于当前二分值\(mid\)的数比小于\(mid\)的数多,说明\( ...
最新文章
- 2018 中国开源年度报告发布,阿里系独占鳌头
- linux自动下载ftp文件夹,Linux 下FTP定时执行批量下载文件
- 洛谷 P1028 数的计算
- 启动Tomcat的时候遇到错误
- linux dns语法检测工具,DNS解析检查工具之nslookup
- 使用CodeIgniter
- Microsoft宣布为Power BI提供AI模型构建器,关键驱动程序分析和Azure机器学习集成...
- 如果生活中没有数学,那么。。。
- Window系统下安装Redis
- Spring Cloud微服务之模块依赖修改(六)
- python写入mysql乱码_python MYsql中文乱码
- 如何在ant里import
- 创建一个SpringBoot项目(IDEA版本,保姆级教程)
- EPLAN p8 安装失败解决办法
- Vblog#2 DAY1
- 推荐几款优秀的开源博客系统
- IntelliJ IDEA 最新注册码(截止到2019年12月12日)
- Invalid packaging for parent POM x, must be “pom“ but is “jar“ @
- 【周志华机器学习】十二、计算学习
- 前端开发规范【范本】
热门文章
- python读取字典元素笔记_python学习笔记:字典的使用示例详解
- 在计算机硬盘中没有什么,如果在打开计算机后找不到硬盘,应该怎么办?
- c语言中freopen函数,fopen和freopen_C中freopen和fopen的区别(用法+详解+区别)
- xampp mysql 内存溢出_php - SQLSTATE [HY000] [2002]连接被拒绝 - 堆栈内存溢出
- producer send源码_RocketMq系列之Producer顺序消息发送源码分析(四)
- python 实现点击右键用某个程序打开功能_4.PYTHON开发利器之使用VS Code进行python程序开发...
- 【Chocolatey】查找包
- mysql升级回退_Mysql 升级、用户与授权,
- easyui js解析字符串_js相关:详解Jquery Easyui的验证扩展
- 4g网络什么时候淘汰_5G时代,4G将淘汰?4G手机会不会像2g,突然失去网络