Description

  一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整。
  给你一个长度为n的序列s。
  回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c,d]之间的子序列中,最大的中位数。
  其中a<b<c<d。
  位置也从0开始标号。
  我会使用一些方式强制你在线。

Input

  第一行序列长度n。
  接下来n行按顺序给出a中的数。
  接下来一行Q。
  然后Q行每行a,b,c,d,我们令上个询问的答案是x(如果这是第一个询问则x=0)。
  令数组q={(a+x)%n,(b+x)%n,(c+x)%n,(d+x)%n}。
  将q从小到大排序之后,令真正的要询问的a=q[0],b=q[1],c=q[2],d=q[3]。
  输入保证满足条件。

Output

  Q行依次给出询问的答案。

Sample Input


Sample Output


HINT

  0:n,Q<=100

  1,...,5:n<=2000

  0,...,19:n<=20000,Q<=25000

Solution

一道神奇的题目,在长沙培训时初次见面

和一般主席树的做法不尽相同

为了避免枚举中位数,我们将序列排序,对排序后的点建立一颗以整个序列编号为节点的线段树

此后,对于每个有序点的线段树,我们将其内的所有值小于它的点的贡献标记为-1,记录从左边起最大连续和,还有从右边起最大连续和

显然,这个排序后的主席树是满足二分性质的

那么,我们二分中位数,查询区间[B,C]的贡献、[A,B)的右边最大连续和、(C,D]的左边最大连续和是否大于或等于0,若是,则说明它可以构成一个合法的中位数是当前二分值的序列,也说明中位数大于或等于当前此数

最后输出二分答案即可

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 20200
#define mid ((s) + (t) >> (1))
#define dmax(a, b) ((a) > (b) ? (a) : (b)) using namespace std; inline int Rin(){
int x = , c = getchar(), f = ;
for(; c < || c > ; c = getchar())
if(!(c ^ ))f = -;
for(; c > && c < ; c = getchar())
x = (x << ) + (x << ) + c - ;
return x * f;
} int n; namespace Arcueid{
struct Area{
int lq, rq, sum; Area(int x = ){
lq = rq = dmax(x, );
sum = x;
}
}; Area operator + (Area a, Area b){
Area c;
c.sum = a.sum + b.sum;
c.lq = dmax(a.lq, a.sum + b.lq);
c.rq = dmax(b.rq, a.rq + b.sum);
return c;
} struct Node{
Node *l, *r;
Area key;
Node(){}
Node(Node *_l, Node *_r, Area _key) : l(_l), r(_r), key(_key) {}
}*_nil = new Node(), *nil = (*_nil = Node(_nil, _nil, ), _nil), pool[N * ], *top = pool, *rt[N];
Node *newnode(Node *_, Node *__, Area ___){
*top = Node(_, __, ___);
return top++;
} Node *born(int s, int t){
if(!(s ^ t))return newnode(0x0, 0x0, Area());
Node *_ = born(s, mid); Node *__ = born(mid + , t);
return newnode(_, __, _->key + __->key);
} Node *real(Node *p, int s, int t, int k){
if(!(s ^ t))return newnode(0x0, 0x0, Area(-));
if(k <= mid){
Node *_ = real(p->l, s, mid, k);
return newnode(_, p->r, _->key + p->r->key);
}
else{
Node *_ = real(p->r, mid + , t, k);
return newnode(p->l, _, p->l->key + _->key);
}
} Area secret(Node *p, int s, int t, int l, int r){
if(l == s && t == r)return p->key;
if(r <= mid)return secret(p->l, s, mid, l, r);
if(l > mid)return secret(p->r, mid + , t, l, r);
return secret(p->l, s, mid, l, mid) + secret(p->r, mid + , t, mid + , r);
} bool judge(int A, int B, int C, int D, int k){
int res = ;
res += secret(rt[k], , n, B, C).sum;
res += secret(rt[k], , n, A, B - ).rq;
res += secret(rt[k], , n, C + , D).lq;
return res >= ;
} int binsearch(int A, int B, int C, int D){
int s = , t = n;
while(s + < t){
if(judge(A, B, C, D, mid))
s = mid;
else
t = mid;
}
if(judge(A, B, C, D, t))
return t;
return s;
}
} namespace moon{
struct dat{
int key, pos; void init(int _) {key = Rin(); pos = _;} bool operator < (const dat h)const{
return key < h.key;
}
}b[N]; void cause(){
n = Rin();
for(int i = ; i <= n; i++)
b[i].init(i);
sort(b + , b + + n);
Arcueid::rt[] = Arcueid::born(, n);
for(int i = ; i <= n; i++)
Arcueid::rt[i] = Arcueid::real(Arcueid::rt[i - ], , n, b[i - ].pos);
int m = Rin(), ans = , q[];
while(m--){
for(int j=;j<;j++)
q[j] = Rin(), q[j] = (q[j] + ans) % n+;
sort(q,q+);
printf("%d\n", ans = b[Arcueid::binsearch(q[],q[],q[],q[])].key);
}
}
} int main(){
moon::cause();
return ;
}

[bzoj2653][middle] (二分 + 主席树)的更多相关文章

  1. BZOJ2653 middle 【主席树】【二分】*

    BZOJ2653 middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个长度为n的序列s.回答Q个这样 ...

  2. BZOJ2653 middle 【二分 + 主席树】

    题目 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c ...

  3. 【BZOJ2653】Middle(主席树)

    [BZOJ2653]Middle(主席树) 题面 BZOJ 洛谷 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你 ...

  4. 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】

    题目链接 洛谷P4559 题解 只会做\(70\)分的\(O(nlog^2n)\) 如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑 找到这些空 ...

  5. 【BZOJ 4556】[Tjoi2016&Heoi2016]字符串 SAM+二分+主席树

    这道题市面上就两种法:一种是SA+二分+主席树,一种是SAM+二分+主席树(有不少人打线段树合并???)(除此之外还有一种利用炒鸡水的数据的暴力SA,贼快.....)(当时学SA的时候没做这道题,现在 ...

  6. 【BZOJ2653】middle(主席树,二分)

    题意:一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[ ...

  7. 【洛谷2839/BZOJ2653】middle(主席树)

    题目: 洛谷2839 分析: 记\(s_i\)表示原序列中第\(i\)大的数. 考虑对于任意一个区间\([a,b]\),设它的中位数为\(s_m\),那么这个区间内大于等于\(s_m\)的数和小于\( ...

  8. 「BZOJ 2653」middle「主席树」「二分」

    题意 一个长度为\(n\)的序列\(a\),设其排过序之后为\(b\),其中位数定义为\(b[n/2]\),其中\(a,b\)从\(0\)开始标号,除法取下整.给你一个长度为\(n\)的序列\(s\) ...

  9. Codeforces Round #276 (Div. 1) E. Sign on Fence 二分+主席树

    E. Sign on Fence   Bizon the Champion has recently finished painting his wood fence. The fence consi ...

随机推荐

  1. Android okHttp网络请求之Json解析

    前言: 前面两篇文章介绍了基于okHttp的post.get请求,以及文件的上传下载,今天主要介绍一下如何和Json解析一起使用?如何才能提高开发效率? okHttp相关文章地址: Android o ...

  2. 从零开始编写自己的C#框架(11)——创建解决方案

    这段时间一直在充电,拜读了园子中大神们的博文(wayfarer的<设计之道>.TerryLee的<.NET设计模式系列文章>.卡奴达摩的<设计模式>还有其他一些零散 ...

  3. MySql - InnoDB - 事务 , Php版

    (出处:http://www.cnblogs.com/linguanh/) 1,前序 由于要重构APP(社交类) 服务端接口的部分代码,故接触到了 innoDB,以及事务这个词,下面主要是以例子的形式 ...

  4. ASP.NET Core 中文文档 第四章 MVC(2.2)模型验证

    原文:Model Validation 作者:Rachel Appel 翻译:娄宇(Lyrics) 校对:孟帅洋(书缘) 在这篇文章中: 章节: 介绍模型验证 验证 Attribute 模型状态 处理 ...

  5. MVC树控件,mvc中应用treeview,实现复选框树的多层级表单控件

    类似于多层级的角色与权限控制功能,用MVC实现MVC树控件,mvc中应用treeview,实现复选框树的多层级表单控件.最近我们的项目中需要用到树型菜单,以前使用WebForm时,树型菜单有微软提供的 ...

  6. QML 从无到有 3 (自动更新)

    新的需求出来啦,需要自动更新功能,不怕程序升级了. 自动更新,QML不好写,需要c++来辅助,这里就涉及QML中调用c++功能(这里就不写了,百度一下,很多). 思路:获取版本>下载程序> ...

  7. SQL Server导入数据时“启用标示插入”详解

    在SQL Server中导入数据时,会有一个"启用标示插入"的选项,突然间懵逼了,这到底啥意思?我选与不选这个选项,结果好像没区别!不科学啊这,"存在即合理", ...

  8. python语言中的编码问题(续)

    上文提到了python开发中非常重要的两处设置. 一个是编解码器的默认设置defaultencoding >>> import sys >>> sys.getdef ...

  9. 地图中插入表格——ArcMap篇

    在制作专题图的过程中,不但要有地理要素表示空间位置,经常还要在图的周围制作一些表格数据.这里对ArcMap中的插入方法进行总结. 方法一:插入对象 利用菜单中的"插入"-" ...

  10. VBA 格式化字符串 - Format大全

    VBA 格式化字符串 VBA 的 Format 函数与工作表函数 TEXT 用法基本相同,但功能更加强大,许多格式只能用于VBA 的 Format 函数,而不能用于工作表函数 TEXT ,以下是本人归 ...