「国家集训队」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. AcWing 870. 约数个数

    #include <iostream> #include <algorithm> #include <unordered_map> #include <vec ...

  2. 【python】anaconda中打开IDLE(python 自带编辑器)

    最近要参加蓝桥杯了,发现 python 的编辑器是使用 python 自带的 IDLE,电脑上只用 Anaconda,就来找一下 打开 .\Anaconda3\Scripts\idel.exe 打开 ...

  3. 【转】解决jenkins自动杀掉衍生进程

    在执行 shell输入框中加入BUILD_ID=dontKillMe ,即可防止jenkins杀死启动的进程 export BUILD_ID=dontKillMe PROJECT_LOCATION=& ...

  4. 寒假安卓app开发学习记录(1)

    今天是安卓软件开发的第一天.虽然之前有了对javaweb的学习,但是对基于安卓的软件开发还是一无所知.所以,第一步就是寻找学习资源,从慕课网上还有菜鸟教程上都找到了对应的教程.然后就开始了开发的第一步 ...

  5. Git - 后续

    1. 概述 现在讲了这些, 也就能应付一下日常的单机操作 后续大概会讲这些内容 分之间的 merge 本地仓库与远程仓库的互动

  6. Codeforces Round #618 (Div. 1)C(贪心)

    把所有数看作N块,后面的块比前面的块小的话就合并,这个过程可能会有很多次,因为后面合并后会把前面的块均摊地更小,可能会影响更前面地块,像是多米诺骨牌效应,从后向前推 #define HAVE_STRU ...

  7. php的排序函数

    sort(array,sortingtype); 参数 描述 array 必需.规定要进行排序的数组. sortingtype 可选.规定如何比较数组的元素/项目.可能的值: 0 = SORT_REG ...

  8. 生成SSH密钥过程

    1.查看是否已经有了ssh密钥:cd ~/.ssh 如果没有密钥则不会有此文件夹,有则备份删除 2.生存密钥: $ ssh-keygen -t rsa -C "name@doumi.com& ...

  9. CSS3的一个伪类选择器:nth-child()

    CSS3的一个伪类选择器“:nth-child()”. Table表格奇偶数行定义样式: 语法: :nth-child(an+b) 为什么选择她,因为我认为,这个选择器是最多学问的一个了.很可惜,据我 ...

  10. 4、maven——构建生命周期

    什么是生命周期? 构建生命周期是一组阶段的序列(sequence of phase),每个阶段定义了目标被执行的顺序,这里的阶段就是生命周期的一部分. 一个典型的Maven生命周期由一些几个阶段的序列 ...