【LG2839】[国家集训队]middle

题面

洛谷

题解

按照求中位数的套路,我们二分答案\(mid\),将大于等于\(mid\)的数设为\(1\),否则为\(-1\)。

若一个区间和大于等于\(0\),则答案可以更大,反之亦然。

对于这个题,我们只要维护出\([b+1,c-1]\)之间二分答案后的和,\([a,b]\)的最大右段和,\([c,d]\)的最大左段和,判断这三项加起来是否大于零即可。

我们维护这三项和的话,按照权值为前缀,建主席树就行了。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int MAX_N = 2e4 + 5;
struct Info {
int lmax, rmax, sum;
Info () {lmax = rmax = -1, sum = 0; }
Info (int lmax, int rmax, int sum) : lmax(lmax), rmax(rmax), sum(sum) { }
} ;
Info operator + (Info l, Info r) {
Info res;
res.lmax = max(l.lmax, l.sum + r.lmax);
res.rmax = max(r.rmax, r.sum + l.rmax);
res.sum = l.sum + r.sum;
return res;
}
struct Node { int ls, rs; Info v; } t[MAX_N * 20];
int rt[MAX_N], tot = 0;
void build(int &o, int l, int r) {
o = ++tot;
t[o].v = (Info){r - l + 1, r - l + 1, r - l + 1};
if (l == r) return ;
int mid = (l + r) >> 1;
build(t[o].ls, l, mid);
build(t[o].rs, mid + 1, r);
}
void insert(int &o, int p, int l, int r, int pos) {
o = ++tot, t[o] = t[p];
if (l == r) return (void)(t[o].v = (Info){-1, -1, -1});
int mid = (l + r) >> 1;
if (pos <= mid) insert(t[o].ls, t[p].ls, l, mid, pos);
else insert(t[o].rs, t[p].rs, mid + 1, r, pos);
t[o].v = t[t[o].ls].v + t[t[o].rs].v;
}
Info query(int o, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return t[o].v;
int mid = (l + r) >> 1; Info res;
if (ql <= mid) res = res + query(t[o].ls, l, mid, ql, qr);
if (qr > mid) res = res + query(t[o].rs, mid + 1, r, ql, qr);
return res;
}
int N, id[MAX_N], a[MAX_N], q[5];
bool check(int mid) {
int val = 0;
if (q[1] + 1 <= q[2] - 1) val += query(rt[mid], 1, N, q[1] + 1, q[2] - 1).sum;
val += query(rt[mid], 1, N, q[0], q[1]).rmax;
val += query(rt[mid], 1, N, q[2], q[3]).lmax;
return val >= 0;
}
bool cmp(const int &x, const int &y) { return a[x] < a[y]; }
int main() {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
#endif
N = gi(); build(rt[1], 1, N);
for (int i = 1; i <= N; i++) a[i] = gi(), id[i] = i;
sort(&id[1], &id[N + 1], cmp);
for (int i = 2; i <= N; i++) insert(rt[i], rt[i - 1], 1, N, id[i - 1]);
for (int Q = gi(), ans = 0; Q--; ) {
for (int i = 0; i < 4; i++) q[i] = (gi() + ans) % N + 1;
sort(&q[0], &q[4]);
int l = 1, r = N;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) ans = a[id[mid]], l = mid + 1;
else r = mid - 1;
}
printf("%d\n", ans);
}
return 0;
}

【LG2839】[国家集训队]middle的更多相关文章

  1. [国家集训队]middle 解题报告

    [国家集训队]middle 主席树的想法感觉挺妙的,但是这题数据范围这么小,直接分块草过去不就好了吗 二分是要二分的,把\(<x\)置\(-1\),\(\ge x\)的置\(1\),于是我们需要 ...

  2. [国家集训队]middle

    [国家集训队]middle 题目 解法 开\(n\)颗线段树,将第\(i\)颗线段树中大于等于第\(i\)小的数权值赋为1,其他的则为-1,对于每个区间维护一个区间和,最大前缀和,最大后缀和. 然后二 ...

  3. P2839 [国家集训队]middle

    P2839 [国家集训队]middle 好妙的题啊,,,, 首先二分一个答案k,把数列里>=k的数置为1,=0就是k>=中位数,<0就是k<中位数 数列的最大和很好求哇 左边的 ...

  4. CF484E Sign on Fence && [国家集训队]middle

    CF484E Sign on Fence #include<bits/stdc++.h> #define RG register #define IL inline #define _ 1 ...

  5. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

  6. luogu2839 [国家集训队]middle

    题目链接:洛谷 题目大意:给定一个长度为$n$的序列,每次询问左端点在$[a,b]$,右端点在$[c,d]$的所有子区间的中位数的最大值.(强制在线) 这里的中位数定义为,对于一个长度为$n$的序列排 ...

  7. 解题:国家集训队 Middle

    题面 求中位数的套路:二分,大于等于的设为1,小于的设为-1 于是可以从小到大排序后依次加入可持久化线段树,这样每次只会变化一个位置 那左右端点是区间怎么办? 先把中间的算上,然后维护每个区间左右两侧 ...

  8. [洛谷P2839][国家集训队]middle

    题目大意:给你一个长度为$n$的序列$s$.$Q$个询问,问在$s$中的左端点在$[a,b]$之间,右端点在$[c,d]$之间的子段中,最大的中位数. 强制在线. 题解:区间中位数?二分答案,如果询问 ...

  9. Luogu 2839 [国家集训队]middle

    感觉这题挺好的. 首先对于中位数最大有一个很经典的处理方法就是二分,每次二分一个数组中的下标$mid$,然后我们把$mid$代回到原来的数组中检查,如果一个数$a_{i} \geq mid$,那么就把 ...

随机推荐

  1. 【转载】socket通信-C#实现tcp收发字符串文本数据

    在日常碰到的项目中,有些场景需要发送文本数据,也就是字符串,比如简单的聊天文字,JSON字符串等场景.那么如何如何使用SharpSocket来收发此类数据呢?其中要掌握的关键点是什么呢? 点击查看原博 ...

  2. 笔记:Java Language Specification - 章节17- 线程和锁

    回答一个问题:多线程场景下,有时一个线程对shared variable的修改可能对另一个线程不可见.那么,何时一个线程对内存的修改才会对另一个线程可见呢? 基本的原则: 如果 读线程 和 写线程 不 ...

  3. linq自定义条件Lambda过滤方法

    Public Func<NoramalClass,bool>simpleComare<NormalClass>(string property,object value) { ...

  4. Nginx学习(二)

    ------------恢复内容开始------------ Nginx配置文件 主配置文件结构:四部分 main block:主配置段,既全局配置段,对Http,mail都有效 event{ }事件 ...

  5. oracle 排序后分页查询

    demo: select * from ( select * from DEV_REG_CFG_CAMERA where 1 = 1 order by unid asc) where rownum & ...

  6. Odoo中的模型继承、视图继承、Qweb模板继承详解

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826114.html 在实际开发过程中,经常会遇到需要修改Odoo原生逻辑的情况.然而,直接修改Odoo底 ...

  7. Windows & Ubuntu 双系统完美卸载Ubuntu(不残留,无污染)

    双系统卸载Ubuntu时,如若直接从Windows磁盘管理里格式化Ubuntu分区,由于Ubuntu的引导盘的原因,会导致电脑启动时出现问题,所以不建议这样的操作. 卸载Ubuntu前需要区分BIOS ...

  8. Python socket基本写法

    TCP:长连接,安全可靠,不会丢包,但是会发生黏包,面向流的传输,超长的数据包会被拆包发送 多条send的小数据会连在一起发送,造成黏包现象,是tcp协议内部的优化算法造成的 如果要发送特别大的数据时 ...

  9. 用于Python扩展包的非官方Windows二进制文件

    https://www.lfd.uci.edu/~gohlke/pythonlibs/ Index by date: peewee aiohttp indexed_gzip pygit2 pymatg ...

  10. django云端留言板

    1.创建应用 django-admin startproject cloudms cd cloudms python manage.py startapp msgapp 2.创建模板文件 在cloud ...