【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. ELK学习笔记之Kibana安装配置

    Kibana 是一个开源的分析和可视化平台,是ELK的重要部分.Kibana提供搜索.查看和与存储在 Elasticsearch 索引中的数据进行交互的功能.开发者或运维人员可以轻松地执行高级数据分析 ...

  2. Django:RestFramework之-------认证

    3 restframework-认证 3.1APIView 认证: 认证是否已经登陆,如果已经登陆返回元组,如果没有登陆报错 源码流程: 执行dispatch方法: def dispatch(self ...

  3. js学习之数据结构和算法

    js中的数据结构 1.列表 待办事项列表.购物清单.最佳十名榜单等等. 适用: 1)数据结构较为简单, 2)不需要在一个长序列中查找元素,或者对其进行排序 2.栈 一摞盘子 ----- 添加删除只能从 ...

  4. 通过windowmanager在camera界面上显示内容

    Window与WindowManager机制https://www.jastrelax.com/android/2018-03-08-android-window/ [Android开发艺术探索阅读笔 ...

  5. .NET异步资料收集

    个人认为应该是.NET关于并行编程 / 异步编程最权威的内容来源(虽然看起来里面的内容离现在已经好几年了,但是大部分内容都不过时) https://devblogs.microsoft.com/pfx ...

  6. Spark编译的三种方式

    有三种编译方式,此文采用make-distribution.sh编译 其余两种为maven 和SBT编译 1.配置jdk 配置maven 配置scala 2.修改spark下make-distribu ...

  7. PHP二维数组用某个字段的值当做键名

    $array = array( array(','name'=>'tom'), array(','name'=>'jerry'), array(','name'=>'spike') ...

  8. Linux下 svn相关操作

    Linux下 svn相关操作 一.首先看看svn安装的位置: 命令: find / -name svn /var/svn :表示安装目录 /user/bin/svn :表示命令目录 可以看到的是svn ...

  9. Django 之 Form 组件

    常用功能 From 组件主要有以下几大功能: 生成 HTML 标签 验证用户数据(显示错误信息) HTML Form 提交保留上次提交数据 初始化页面显示内容 小试牛刀 下面我们通过 Form 组件来 ...

  10. css3动画 2D 3D transfrom

    2D transform 例如transform: translate(1px,30px); translate() 方法 translate()方法,根据左(X轴)和顶部(Y轴)位置给定的参数,从当 ...