题目:

洛谷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. 2018百度之星资格赛T2 子串查询

    [题解] 很容易想到暴力做法:对于每个询问暴力查找区间内的最小字母,统计其出现次数.效率O(N^2),无法通过全部数据. 我们可以换一个思路,设f[i][j]为第i个字母(字母‘A'到’Z'分别对应0 ...

  2. PAT 1141 PAT Ranking of Institutions

    After each PAT, the PAT Center will announce the ranking of institutions based on their students' pe ...

  3. Unity常用常找(二)

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/51315050 作者:car ...

  4. Windows Server 2008R2服务器IIS安装步骤

    注意点: 添加ASP.NET ..NET 扩展性.CGI.ISAPI 扩展.ISAPI 筛选器,去掉 目录浏览(因为大多数网站用不到.) 如果需要用到asp则勾选asp,如果需要用shtm需要开启在服 ...

  5. 【Codeforces 464A】No to Palindromes!

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 因为原序列没有任何长度超过2的回文串. 所以,我们在改变的时候,只要时刻保证改变位置s[i]和s[i-1]以及s[i-2]都不相同就好. 因为 ...

  6. Python学习笔记 (1)Hello World(环境搭建+输出Hello World!)

    随想 高考发挥失常.科三遇火车发挥失常,各种不顺……突然发现假期都快没了,才想起高考前想象的这个假期要做的一堆事,现在来多完成一件吧. 这几篇博客仅只是我的学习笔记,凑合看吧.我这个python小白看 ...

  7. [luoguP2875] [USACO07FEB]牛的词汇The Cow Lexicon(DP)

    传送门 f[i] 表示前 i 个字符去掉多少个 的最优解 直接暴力DP ——代码 #include <cstdio> #include <cstring> #include & ...

  8. MTK平台系统稳定性分析

    目录 1:简介 2:怎么抓取和分析log 3:怎么确定问题点 简介 系统稳定性目前主要是解决系统死机重启. 分为两部分:Android /kernel Kernel 分析需要的文件和工具: Mtklo ...

  9. dubbo 学习1

    1.高性能优秀的服务框架,应用可通过高性能的RPC实现服务的输出和输入功能,可以和spring框架无缝集成. 2.主要核心部件 a.remoting 网络通信框架 实现了sync-over-asnc ...

  10. 分享一个灰常好的 dapper 扩展插件: Rainbow

    dapper 是一个效率非常高的orm  框架 ,效率要远远大于 我们大微软的EF .    它只有一个类文件,非常之小.(在 EF 5.0 后 微软已经做了 改进) ps; 由于之前我也没测试过,只 ...