题目:

洛谷2839

分析:

记\(s_i\)表示原序列中第\(i\)大的数。

考虑对于任意一个区间\([a,b]\),设它的中位数为\(s_m\),那么这个区间内大于等于\(s_m\)的数和小于\(s_m\)的数的数量要么相等,要么小于比大于等于多一个。后一种情况当且仅当\(s_m\in [a,b]\)且序列长度为奇数。

考虑如果已知一个数\(s_i\),如何判断是否存在区间\([e,f]\)(\(e\in [a,b],f\in [c,d]\))使\([e,f]\)的中位数大于等于\(s_i\)呢(显然满足条件的\(i\)是单调的,可以二分)?

对于\(s_i\),记所有小于它的数为\(-1\),大于等于它的数为\(1\),那么如果能找到一个符合条件的区间\([e,f]\)使这段区间的和大于等于\(0\)说明最大中位数大于等于\(s_i\),记录答案并尝试更大的\(i\);否则不符合条件,需要调小\(i\)。

此时问题变成了已知一个\(1\)和\(-1\)组成的序列,求一个\([e,f]\)使它的区间和最大。把\([e,f]\)拆成三部分:必选的\((b,c)\),在\([a,b]\)中选一段后缀的\([e,b]\)和在\([c,d]\)中选一段前缀的\([c,f]\)。这个可以用线段树解决,方法类似【Vijos1083/BZOJ1756】小白逛公园(线段树),查询\((b,c)\)的\(val\),\([a,b]\)的\(rm\)和\([c,d]\)的\(lm\)。

\(s_i\)对应的线段树和\(s_{i-1}\)对应的线段树的区别仅仅是把\((i-1)\)位置的\(1\)变成了\(-1\),因此可以用主席树维护节省空间。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
namespace zyt
{
const int N = 2e4 + 10, Q = 2.5e4 + 10;
int n, q, tmp[N], head[N];
pair<int, int> arr[N];
namespace Chairman_Tree
{
const int SUM = 0, SUML = 1, SUMR = 2;
struct node
{
int sum, suml, sumr, s[2];
node(): sum(0), suml(0), sumr(0)
{
s[0] = s[1] = 0;
}
}tree[N * 20];
int cnt;
inline void update(node &now, const node &lt, const node &rt)
{
now.suml = now.sumr = 0;
now.sum = lt.sum + rt.sum;
now.suml = max(lt.suml, lt.sum + rt.suml);
now.sumr = max(rt.sumr, rt.sum + lt.sumr);
}
inline void update(const int rot)
{
update(tree[rot], tree[tree[rot].s[0]], tree[tree[rot].s[1]]);
}
int build(const int lt, const int rt, const int val)
{
int rot = ++cnt;
if (lt == rt)
{
tree[rot].sum = tree[rot].suml = tree[rot].sumr = -1 + 2 * (tmp[lt] >= val);
return rot;
}
int mid = (lt + rt) >> 1;
tree[rot].s[0] = build(lt, mid, val);
tree[rot].s[1] = build(mid + 1, rt, val);
update(rot);
return rot;
}
int change(const int pre, const int lt, const int rt, const int pos, const int x)
{
int rot = ++cnt;
tree[rot] = tree[pre];
if (lt == rt)
{
tree[rot].sum = x;
tree[rot].suml = x;
tree[rot].sumr = x;
return rot;
}
int mid = (lt + rt) >> 1;
if (pos <= mid)
tree[rot].s[0] = change(tree[pre].s[0], lt, mid, pos, x);
else
tree[rot].s[1] = change(tree[pre].s[1], mid + 1, rt, pos, x);
update(rot);
return rot;
}
node query(const int rot, const int lt, const int rt, const int ls, const int rs)
{
if (ls <= lt && rt <= rs)
return tree[rot];
int mid = (lt + rt) >> 1;
if (rs <= mid)
return query(tree[rot].s[0], lt, mid, ls, rs);
else if (ls > mid)
return query(tree[rot].s[1], mid + 1, rt, ls, rs);
else
{
node tmp[2] = {query(tree[rot].s[0], lt, mid, ls, rs),
query(tree[rot].s[1], mid + 1, rt, ls, rs)};
node ans;
update(ans, tmp[0], tmp[1]);
return ans;
}
}
int query(const int rot, const int ls, const int rs, const int type)
{
node ans = query(rot, 0, n - 1, ls, rs);
switch (type)
{
case SUM:
return ans.sum;
case SUML:
return ans.suml;
case SUMR:
return ans.sumr;
}
}
}
int work()
{
using namespace Chairman_Tree;
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for (int i = 0; i < n; i++)
cin >> arr[i].first, arr[i].second = i, tmp[i] = arr[i].first;
sort(arr, arr + n);
head[0] = build(0, n - 1, arr[0].first);
for (int i = 1; i < n; i++)
head[i] = change(head[i - 1], 0, n - 1, arr[i - 1].second, -1);
cin >> q;
int x = 0;
while (q--)
{
int in[4];
for (int i = 0; i < 4; i++)
cin >> in[i], in[i] = (in[i] + x) % n;
sort(in, in + 4);
int l = 0, r = n - 1, ans;
while (l <= r)
{
int mid = (l + r) >> 1;
int tmp = query(head[mid], in[0], in[1], SUMR) + query(head[mid], in[2], in[3], SUML);
if (in[1] + 1 <= in[2] - 1)
tmp += query(head[mid], in[1] + 1, in[2] - 1, SUM);
if (tmp >= 0)
l = mid + 1, ans = mid;
else
r = mid - 1;
}
cout << arr[ans].first << '\n';
x = arr[ans].first;
}
return 0;
}
}
int main()
{
return zyt::work();
}

【洛谷2839/BZOJ2653】middle(主席树)的更多相关文章

  1. 洛谷P2617 Dynamic Rankings (主席树)

    洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...

  2. [BZOJ2653]middle 主席树+二分

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2042  Solved: 1123[Submit][Status][Disc ...

  3. 洛谷P3567 KUR-Couriers [POI2014] 主席树/莫队

    正解:主席树/莫队 解题报告: 传送门! 这题好像就是个主席树板子题的样子,,,? 毕竟,主席树的最基本的功能就是,维护一段区间内某个数字的个数 但是毕竟是刚get到主席树,然后之前做的一直是第k大, ...

  4. 洛谷P3567[POI2014]KUR-Couriers(主席树+二分)

    题意:给一个数列,每次询问一个区间内有没有一个数出现次数超过一半 题解: 最近比赛太多,都没时间切水题了,刚好日推了道主席树裸题,就写了一下 然后 WA80 WA80 WA0 WA90 WA80 ?? ...

  5. 洛谷P3567 [POI2014]KUR-Couriers 主席树

    挺裸的,没啥可讲的. 不带修改的主席树裸题 Code: #include<cstdio> #include<algorithm> using namespace std; co ...

  6. 洛谷$P3302$ 森林 $[SDOI2013]$ 主席树

    正解:主席树 解题报告: 传送门! 口胡一时爽代码火葬场 这题想法不难,,,但显然的是代码应该还挺难打的 但反正我也不放代码,就写下题解趴$QwQ$ 第一问就是个$Count\ on\ a\ tree ...

  7. 洛谷P4602 [CTSC2018]混合果汁(主席树)

    题目描述 小 R 热衷于做黑暗料理,尤其是混合果汁. 商店里有 nn 种果汁,编号为 0,1,\cdots,n-10,1,⋯,n−1 . ii 号果汁的美味度是 d_idi​ ,每升价格为 p_ipi ...

  8. 洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大

    我们将线段树套在树状数组上,查询前预处理出所有要一起移动的节点编号,并在查询过程中一起将这些节点移到左右子树上. Code: #include<cstdio> #include<cs ...

  9. 洛谷4137 mex题解 主席树

    题目链接 虽然可以用离线算法水过去,但如果强制在线不就gg了. 所以要用在线算法. 首先,所有大于n的数其实可以忽略,因为mex的值不可能大于n 我们来设想一下,假设已经求出了从0到n中所有数在原序列 ...

随机推荐

  1. vs2012+ winform+.net4.0发布如何在xp上运行

    今天在英文版vs2013打包发布4.0(非4.0 client)的winform时,遇到了在xp上无法运行的情况,.net framework 4.0在xp上已安装.在打包前,winform工程,即菜 ...

  2. Billboard (HDU 2795)

    Billboard (HDU 2795) Hdu 2795 注意到每个广告的长度是1,因此可以将每这一张广告牌当成一个数列表示,每个初始值为w.使用线段树维护这个数列,每次查询为找到这个数列第一个大于 ...

  3. 如何使用loadrunner进行web网站性能测试

    loadrunner压力测试原理 本质就是在loadrunner上模拟多个用户同时按固定行为访问web站点.其中固定行为在loadrunner中是通过录制脚本定义的,多个用户同时访问的策略是在load ...

  4. JavaScript学习总结(12)——2016 年 7 个顶级 JavaScript 框架

    当涉及到Web开发时,JavaScript框架往往是一些开发人员和企业最受欢迎的平台.可能,你有机会尝试过一两个顶级的JavaScript框架,但你仍然有点不确定哪个才是最佳的最值得掌握的,或者哪个值 ...

  5. Failed to load slave replication state from table mysql.gtid_slave_pos: 1146: Table 'mysql.gtid_slave_pos' doesn't exist

    http://anothermysqldba.blogspot.com/2013/06/mariadb-1003-alpha-install-on-fedora-17.html MariaDB 10. ...

  6. spoj 375 树链剖分模板

    /* 只是一道树链刨分的入门题,作为模板用. */ #include<stdio.h> #include<string.h> #include<iostream> ...

  7. 轰炸III

    题目背景 一个大小为N*M的城市遭到了X次轰炸,每次都炸了一个每条边都与边界平行的矩形. 题目描述 在轰炸后,有Y个关键点,指挥官想知道,它们有没有受到过轰炸,如果有,被炸了几次,最后一次是第几轮. ...

  8. 【Teamviewer】Teamviewer远程访问工具使用方法

    首先电脑必须能访问外网,即使是在局域网内也无所谓. 1.这里以非自动登录.自动受控的方式为例.首先,让对方也安装一个Teamviewer,或运行一个绿色的Teamviewer,并保证网络可通.然后我们 ...

  9. cocos2d-x大版本号3.1系列一

    本人博客,欢迎转载:http://blog.csdn.net/dawn_moon 项目忙完了.继续写我的博客.去cocos2d-x的官网看了下,不出所料.又有惊喜啊.3.0经过几个版本号的迭代,最终迎 ...

  10. Entity Framework性能影响因素分析

    1.对象管理机制-复杂为更好的管理模型对象,EF提供了一套内部管理机制和跟踪对象的状态,保存对象一致性,使用方便,但是性能有所降低. 2.执行机制-高度封装在EF中,所有的查询表达式都会经过语法分析. ...