「国家集训队」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. 有关C/C++中,表达式计算顺序的问题,以及表达式内部变量“副作用”问题(转)

    经常可以在一些讨论组里看到下面的提问:“谁知道下面C语句给n赋什么值?”m = 1; n = m+++m++;最近有位不相识的朋友发email给我,问为什么在某个C++系统里,下面表达式打印出两个4, ...

  2. WSAGetLastError错误原因的博客与时间函数

    https://blog.csdn.net/skc361/article/details/9254507 https://blog.csdn.net/HK_5788/article/details/4 ...

  3. sqli-libs(54-65关)

    Less_54 Less-54:使用’’包裹 对输入的次数做了限制,必须在10次请求之内获取信息,否则会刷新表名 输入:?Id=1’ order by 3--+   查看有多少列: 输入 ?id=-1 ...

  4. Linux04——手动修改IP和关闭防火墙服务

    两种方法手动修改IP: 命令行方式 2. 图形化界面修改 点击应用即可(地址自行设置) 关闭防火墙服务,否则连不上Linux

  5. element 确认框 confirm 的写法

    this.confirm('内容', '标题', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'success', callbac ...

  6. 实现在vue中element-ui的el-dialog弹框拖拽

    参考:实现在vue中element-ui的el-dialog弹框拖拽 1.在 utils 中新建 directives.js 文件 import Vue from 'vue' // v-dialogD ...

  7. dateadd()日期加法运算

  8. dubbo-admin监控台的搭建

    一.dubbo-admin dubbo-admin是dubbo的控制台web程序,可以利用浏览器对dubbo进行性能监控.服务治理.降级.分组以及一些参数的设置.2.6版本及以前打包后是一个war包, ...

  9. tp5 配置 // 视图输出字符串内容替换 'view_replace_str' 的原理

  10. 06-Docker-Image管理操作

    目录 06-Docker-Image管理操作 参考 镜像命名规范 镜像管理命令 1. 拉取推送 2. 查看操作 3. 本地删除 4. 创建标签 5. 导出导入 06-Docker-Image管理操作 ...