「国家集训队」middle

传送门

按照中位数题的套路,二分答案 \(mid\),序列中 \(\ge mid\) 记为 \(1\),\(< mid\) 的记为 \(-1\)

然后只要存在一个区间 \([l, r](l \in [a, b], r \in [c, d])\) 的和 \(\ge 0\) 则答案可以更大,否则就更小。

所以说我们就要算出区间 \([b + 1, c - 1]\) 的和,加上 \([a, b]\) 的最大后缀,还有 \([c, d]\) 最大前缀,加起来就是我们用来 \(check\) 的值。

这些过程可以用线段树来搞,具体维护细节就和维护区间最大子段和差不多。

但是我们面临另一个问题:\(mid\) 会变,也就是我们的序列是会变的,我们不可能对于每一个 \(mid\) 都建一棵线段树。

那能不能用主席树优化空间呢?

我们发现,\(mid\) 扩大 \(1\) ,只会有一个数的值从 \(1\) 变成 \(-1\) ,也就是说我们只需要修改一条链上的信息,这显然可以用主席树来搞,空间问题也就解决了。

参考代码:

#include <algorithm>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
} typedef long long LL;
const int _ = 20005; int n, m, q[5], a[_], id[_], tot, rt[_];
struct node { int lc, rc, sum, L, R; } t[_ << 5]; inline void pushup(int p) {
t[p].sum = t[t[p].lc].sum + t[t[p].rc].sum;
t[p].L = max(t[t[p].lc].L, t[t[p].lc].sum + t[t[p].rc].L);
t[p].R = max(t[t[p].rc].R, t[t[p].rc].sum + t[t[p].lc].R);
} inline void build(int& p, int l = 1, int r = n) {
p = ++tot;
if (l == r) { t[p].sum = t[p].L = t[p].R = 1; return ; }
int mid = (l + r) >> 1;
build(t[p].lc, l, mid), build(t[p].rc, mid + 1, r), pushup(p);
} inline void update(int& p, int q, int x, int l = 1, int r = n) {
t[p = ++tot] = t[q];
if (l == r) { t[p].sum = t[p].L = t[p].R = -1; return ; }
int mid = (l + r) >> 1;
if (x <= mid) update(t[p].lc, t[q].lc, x, l, mid);
else update(t[p].rc, t[q].rc, x, mid + 1, r);
pushup(p);
} inline node query(int ql, int qr, int p, int l = 1, int r = n) {
if (ql <= l && r <= qr) return t[p];
int mid = (l + r) >> 1;
if (qr <= mid) return query(ql, qr, t[p].lc, l, mid);
if (ql > mid) return query(ql, qr, t[p].rc, mid + 1, r);
node ls = query(ql, mid, t[p].lc, l, mid), rs = query(mid + 1, qr, t[p].rc, mid + 1, r);
return (node) { 0, 0, ls.sum + rs.sum, max(ls.L, ls.sum + rs.L), max(rs.R, rs.sum + ls.R) };
} inline bool check(int mid) {
int res = 0;
if (q[1] + 1 <= q[2] - 1) res += query(q[1] + 1, q[2] - 1, rt[mid]).sum;
res += query(q[0], q[1], rt[mid]).R;
res += query(q[2], q[3], rt[mid]).L;
return res >= 0;
} inline bool cmp(int i, int j) { return a[i] < a[j]; } int main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
read(n);
for (rg int i = 1; i <= n; ++i) read(a[i]), id[i] = i;
sort(id + 1, id + n + 1, cmp);
build(rt[1]);
for (rg int i = 2; i <= n; ++i) update(rt[i], rt[i - 1], id[i - 1]);
read(m);
for (rg int ans = 0; m--; ) {
for (rg int i = 0; i < 4; ++i) read(q[i]), q[i] = (q[i] + ans) % n + 1;
sort(q, 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;
}

「国家集训队」middle的更多相关文章

  1. 「国家集训队」小Z的袜子

    「国家集训队」小Z的袜子 传送门 莫队板子题. 注意计算答案的时候,由于分子分母都要除以2,所以可以直接约掉,这样在开桶算的时候也方便一些. 参考代码: #include <algorithm& ...

  2. P4827「国家集训队」 Crash 的文明世界

    「国家集训队」 Crash 的文明世界 提供一种不需要脑子的方法. 其实是看洛谷讨论版看出来的( (但是全网也就这一篇这个方法的题解了) 首先这是一个关于树上路径的问题,我们可以无脑上点分治. 考虑当 ...

  3. Solution -「国家集训队」「洛谷 P2839」Middle

    \(\mathcal{Description}\)   Link.   给定序列 \(\{a_n\}\),\(q\) 组询问,给定 \(a<b<c<d\),求 \(l\le[a,b] ...

  4. 「洛谷1903」「BZOJ2120」「国家集训队」数颜色【带修莫队,树套树】

    题目链接 [BZOJ传送门] [洛谷传送门] 题目大意 单点修改,区间查询有多少种数字. 解法1--树套树 可以直接暴力树套树,我比较懒,不想写. 稍微口胡一下,可以直接来一个树状数组套主席树,也就是 ...

  5. 「国家集训队」Crash的数字表格

    题目描述 求(对 \(20101009\) 取模,\(n,m\le10^7\) ) \[\sum_{i=1}^n\sum_{j=1}^m\operatorname{lcm}(i,j)\] 大体思路 推 ...

  6. Solution -「国家集训队」「洛谷 P2619」Tree I

    \(\mathcal{Description}\)   Link.   给一个 \(n\) 个点 \(m\) 条边的带权无向图,边有权值和黑白颜色,求恰选出 \(K\) 条白边构成的最小生成树.    ...

  7. Solution -「国家集训队」「洛谷 P4451」整数的 lqp 拆分

    \(\mathcal{Description}\)   Link.   求 \[\sum_{m>0\\a_{1..m}>0\\a_1+\cdots+a_m=n}\prod_{i=1}^mf ...

  8. [国家集训队2012]middle

    http://cogs.pro:8080/cogs/problem/problem.php?pid=1763 二分答案x 把区间内>=x的数设为1,<x的数设为-1 左端点在[a,b]之间 ...

  9. [国家集训队2012]middle(陈立杰)

    我是萌萌的传送门 我是另一个萌萌的传送门 脑残错误毁一下午…… 其实题解早就烂大街了,然而很久之前我只知道是二分答案+主席树却想不出来这俩玩意儿怎么一块儿用的……今天又翻了几篇题解才恍然大悟,是把权值 ...

随机推荐

  1. mongo的常用命令--转载

    转载liyonghui的博文,出处  http://www.cnblogs.com/liyonghui/p/mongodb.html 博主写的特别好,对于我这个新手帮了大忙了,还将mongo和mysq ...

  2. python面向对象封装案例2

    封装 封装 是面向对象编程的一大特点 面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中 外界 使用 类 创建 对象,然后 让对象调用方法 对象方法的细节 都被 封装 在 类 ...

  3. 阻塞式I/0 和 非阻塞式I/O 同步异步详细介绍

    请求描述: `阻塞/非阻塞` 和 `同步/异步` 不是一个概念.举几个简单的例子. 当进程调用一个进行IO操作的API时(比如read函数),在数据没有到达前,read 会挂起,进程会卡住.在数据读取 ...

  4. report_delay_calculation/check_timing/report_annotated_parasitics/report_analysis_coverge

    如何debug 一颗cell 或一段net 的delay,  常用的办法是用report_delay_calculation 报这颗cell 或这段net, 会得到形式如下的report, 从该rep ...

  5. Linux按文件名搜索命令

    find 搜索目录 -name 目标名字 find / -name file名 /代表是全盘搜索,也可以指定目录搜索 find 搜索文件的命令格式: find [搜索范围] [匹配条件] 选项: -n ...

  6. Spring Boot整合EhCache

    本文讲解Spring Boot与EhCache的整合. 1 EhCache简介 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认CacheProvid ...

  7. Yii2.0如何建立公共方法

    yii2-advanced版本 common 目录为公共资源目录,我们可以把定义的方法放在这个目录下,在此目录下我们随意建立一个文件比如”helps”目录,因为考虑到公共方法可能会有功能上的划分类,所 ...

  8. 【CSS属性#2】

    " 目录 一.盒子模型 二.外边距 margin 三.内填充 padding 四.浮动 float 五.清除浮动 clear 六.溢出 overflow 七.定位 position 1. 无 ...

  9. iOS 开发之使用链式编程思想实现简单的计算器

    链式编程思想是将多个操作(多行代码)通过点号(.)链接在一起成为一句代码,使代码可读性好.例如 a(1).b(2).c(3). 链式编程思想最为关键的是,方法的返回值是block,block必须返回对 ...

  10. 03-Docker-Engine详解

    目录 03-Docker-Engine详解 摆脱 LXC 摒弃大而全的 Docker daemon 开放容器计划(OCI)的影响 runc containerd 启动一个新的容器 该模型的显著优势 s ...